porffor 0.58.18 → 0.58.19
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 +13 -0
- package/compiler/builtins/array.ts +48 -0
- package/compiler/builtins/regexp.ts +14 -7
- package/compiler/builtins/string.ts +75 -12
- package/compiler/builtins/string_f64.ts +19 -0
- package/compiler/builtins_precompiled.js +589 -541
- package/compiler/codegen.js +5 -96
- package/compiler/precompile.js +1 -1
- package/package.json +1 -1
- package/runtime/index.js +1 -1
- package/wow.js +1 -0
- package/compiler/prototype.js +0 -407
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
|
@@ -114,6 +114,54 @@ export const __Array_prototype_push = (_this: any[], ...items: any[]) => {
|
|
114
114
|
return _this.length = len + itemsLen;
|
115
115
|
};
|
116
116
|
|
117
|
+
export const __Array_prototype_pop = (_this: any[]) => {
|
118
|
+
const len: i32 = _this.length;
|
119
|
+
if (len == 0) return undefined;
|
120
|
+
|
121
|
+
const lastIndex: i32 = len - 1;
|
122
|
+
const element: any = _this[lastIndex];
|
123
|
+
_this.length = lastIndex;
|
124
|
+
|
125
|
+
return element;
|
126
|
+
};
|
127
|
+
|
128
|
+
export const __Array_prototype_shift = (_this: any[]) => {
|
129
|
+
const len: i32 = _this.length;
|
130
|
+
if (len == 0) return undefined;
|
131
|
+
|
132
|
+
const element: any = _this[0];
|
133
|
+
_this.length = len - 1;
|
134
|
+
|
135
|
+
// shift all elements left by 1 using memory.copy
|
136
|
+
Porffor.wasm`;; ptr = ptr(_this) + 4
|
137
|
+
local #shift_ptr i32
|
138
|
+
local.get ${_this}
|
139
|
+
i32.to_u
|
140
|
+
i32.const 4
|
141
|
+
i32.add
|
142
|
+
local.set #shift_ptr
|
143
|
+
|
144
|
+
;; dst = ptr (start of array)
|
145
|
+
local.get #shift_ptr
|
146
|
+
|
147
|
+
;; src = ptr + 9 (second element)
|
148
|
+
local.get #shift_ptr
|
149
|
+
i32.const 9
|
150
|
+
i32.add
|
151
|
+
|
152
|
+
;; size = (len - 1) * 9
|
153
|
+
local.get ${len}
|
154
|
+
i32.to_u
|
155
|
+
i32.const 1
|
156
|
+
i32.sub
|
157
|
+
i32.const 9
|
158
|
+
i32.mul
|
159
|
+
|
160
|
+
memory.copy 0 0`;
|
161
|
+
|
162
|
+
return element;
|
163
|
+
};
|
164
|
+
|
117
165
|
export const __Array_prototype_unshift = (_this: any[], ...items: any[]) => {
|
118
166
|
let len: i32 = _this.length;
|
119
167
|
const itemsLen: i32 = items.length;
|
@@ -57,6 +57,13 @@ export const __Porffor_array_fastPushI32 = (arr: any[], el: any): i32 => {
|
|
57
57
|
return len;
|
58
58
|
};
|
59
59
|
|
60
|
+
export const __Porffor_array_fastPopI32 = (arr: any[]): i32 => {
|
61
|
+
let len: i32 = arr.length;
|
62
|
+
const ret: any = arr[--len];
|
63
|
+
arr.length = len;
|
64
|
+
return ret;
|
65
|
+
};
|
66
|
+
|
60
67
|
export const __Porffor_regex_compile = (patternStr: bytestring, flagsStr: bytestring): RegExp => {
|
61
68
|
const ptr: i32 = Porffor.allocate();
|
62
69
|
Porffor.wasm.i32.store(ptr, patternStr, 0, 0);
|
@@ -341,21 +348,21 @@ export const __Porffor_regex_compile = (patternStr: bytestring, flagsStr: bytest
|
|
341
348
|
|
342
349
|
let thisAltDepth: i32 = altDepth[groupDepth];
|
343
350
|
while (thisAltDepth-- > 0) {
|
344
|
-
const jumpPtr: i32 =
|
351
|
+
const jumpPtr: i32 = Porffor.array.fastPopI32(altStack);
|
345
352
|
Porffor.wasm.i32.store16(jumpPtr, bcPtr - jumpPtr, 0, 1);
|
346
353
|
}
|
347
354
|
altDepth[groupDepth] = 0;
|
348
355
|
|
349
356
|
groupDepth -= 1;
|
350
357
|
|
351
|
-
const capturePop: i32 =
|
358
|
+
const capturePop: i32 = Porffor.array.fastPopI32(groupStack);
|
352
359
|
if (capturePop != -1) {
|
353
360
|
Porffor.wasm.i32.store8(bcPtr, 0x31, 0, 0); // end capture
|
354
361
|
Porffor.wasm.i32.store8(bcPtr, capturePop, 0, 1);
|
355
362
|
bcPtr += 2;
|
356
363
|
}
|
357
364
|
|
358
|
-
const groupStartPtr: i32 =
|
365
|
+
const groupStartPtr: i32 = Porffor.array.fastPopI32(groupStack);
|
359
366
|
lastWasAtom = true;
|
360
367
|
lastAtomStart = groupStartPtr;
|
361
368
|
continue;
|
@@ -751,7 +758,7 @@ export const __Porffor_regex_compile = (patternStr: bytestring, flagsStr: bytest
|
|
751
758
|
|
752
759
|
let thisAltDepth: i32 = altDepth[groupDepth];
|
753
760
|
while (thisAltDepth-- > 0) {
|
754
|
-
const jumpPtr: i32 =
|
761
|
+
const jumpPtr: i32 = Porffor.array.fastPopI32(altStack);
|
755
762
|
Porffor.wasm.i32.store16(jumpPtr, bcPtr - jumpPtr, 0, 1);
|
756
763
|
}
|
757
764
|
altDepth[groupDepth] = 0;
|
@@ -1032,9 +1039,9 @@ export const __Porffor_regex_interpret = (regexp: RegExp, input: i32, isTest: bo
|
|
1032
1039
|
if (backtrack) {
|
1033
1040
|
if (backtrackStack.length == 0) break;
|
1034
1041
|
// Porffor.log(`backtrack! before: captures.length = ${captures.length}, sp = ${sp}, pc = ${pc}`);
|
1035
|
-
captures.length =
|
1036
|
-
sp =
|
1037
|
-
pc =
|
1042
|
+
captures.length = Porffor.array.fastPopI32(backtrackStack);
|
1043
|
+
sp = Porffor.array.fastPopI32(backtrackStack);
|
1044
|
+
pc = Porffor.array.fastPopI32(backtrackStack);
|
1038
1045
|
// Porffor.log(`backtrack! after: captures.length = ${captures.length}, sp = ${sp}, pc = ${pc}`);
|
1039
1046
|
}
|
1040
1047
|
}
|
@@ -353,6 +353,77 @@ export const __Porffor_strcat = (a: any, b: any): any => {
|
|
353
353
|
};
|
354
354
|
|
355
355
|
|
356
|
+
|
357
|
+
export const __String_prototype_at = (_this: string, index: number) => {
|
358
|
+
const len: i32 = _this.length;
|
359
|
+
|
360
|
+
index |= 0;
|
361
|
+
if (index < 0) index = len + index;
|
362
|
+
if (Porffor.fastOr(index < 0, index >= len)) return undefined;
|
363
|
+
|
364
|
+
let out: string = Porffor.allocateBytes(8);
|
365
|
+
Porffor.wasm.i32.store(out, 1, 0, 0); // out.length = 1
|
366
|
+
|
367
|
+
Porffor.wasm.i32.store16(
|
368
|
+
Porffor.wasm`local.get ${out}`,
|
369
|
+
Porffor.wasm.i32.load16_u(Porffor.wasm`local.get ${_this}` + index * 2, 0, 4),
|
370
|
+
0, 4);
|
371
|
+
|
372
|
+
return out;
|
373
|
+
};
|
374
|
+
|
375
|
+
export const __ByteString_prototype_at = (_this: bytestring, index: number) => {
|
376
|
+
const len: i32 = _this.length;
|
377
|
+
|
378
|
+
index |= 0;
|
379
|
+
if (index < 0) index = len + index;
|
380
|
+
if (Porffor.fastOr(index < 0, index >= len)) return undefined;
|
381
|
+
|
382
|
+
let out: bytestring = Porffor.allocateBytes(8);
|
383
|
+
Porffor.wasm.i32.store(out, 1, 0, 0); // out.length = 1
|
384
|
+
|
385
|
+
Porffor.wasm.i32.store8(
|
386
|
+
Porffor.wasm`local.get ${out}`,
|
387
|
+
Porffor.wasm.i32.load8_u(Porffor.wasm`local.get ${_this}` + index, 0, 4),
|
388
|
+
0, 4);
|
389
|
+
|
390
|
+
return out;
|
391
|
+
};
|
392
|
+
|
393
|
+
export const __String_prototype_charAt = (_this: string, index: number) => {
|
394
|
+
const len: i32 = _this.length;
|
395
|
+
|
396
|
+
index |= 0;
|
397
|
+
if (Porffor.fastOr(index < 0, index >= len)) return '';
|
398
|
+
|
399
|
+
let out: string = Porffor.allocateBytes(8);
|
400
|
+
Porffor.wasm.i32.store(out, 1, 0, 0); // out.length = 1
|
401
|
+
|
402
|
+
Porffor.wasm.i32.store16(
|
403
|
+
Porffor.wasm`local.get ${out}`,
|
404
|
+
Porffor.wasm.i32.load16_u(Porffor.wasm`local.get ${_this}` + index * 2, 0, 4),
|
405
|
+
0, 4);
|
406
|
+
|
407
|
+
return out;
|
408
|
+
};
|
409
|
+
|
410
|
+
export const __ByteString_prototype_charAt = (_this: bytestring, index: number) => {
|
411
|
+
const len: i32 = _this.length;
|
412
|
+
|
413
|
+
index |= 0;
|
414
|
+
if (Porffor.fastOr(index < 0, index >= len)) return '';
|
415
|
+
|
416
|
+
let out: bytestring = Porffor.allocateBytes(8);
|
417
|
+
Porffor.wasm.i32.store(out, 1, 0, 0); // out.length = 1
|
418
|
+
|
419
|
+
Porffor.wasm.i32.store8(
|
420
|
+
Porffor.wasm`local.get ${out}`,
|
421
|
+
Porffor.wasm.i32.load8_u(Porffor.wasm`local.get ${_this}` + index, 0, 4),
|
422
|
+
0, 4);
|
423
|
+
|
424
|
+
return out;
|
425
|
+
};
|
426
|
+
|
356
427
|
export const __String_prototype_toUpperCase = (_this: string) => {
|
357
428
|
// todo: unicode not just ascii
|
358
429
|
const len: i32 = _this.length;
|
@@ -878,7 +949,6 @@ export const __String_prototype_padStart = (_this: string, targetLength: number,
|
|
878
949
|
|
879
950
|
let outPtr: i32 = Porffor.wasm`local.get ${out}`;
|
880
951
|
let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
|
881
|
-
// const padStringPtr: i32 = Porffor.wasm`local.get ${padString}`;
|
882
952
|
|
883
953
|
const len: i32 = _this.length;
|
884
954
|
|
@@ -897,8 +967,7 @@ export const __String_prototype_padStart = (_this: string, targetLength: number,
|
|
897
967
|
const padStringLen: i32 = padString.length;
|
898
968
|
if (padStringLen > 0) {
|
899
969
|
for (let i: i32 = 0; i < todo; i++) {
|
900
|
-
|
901
|
-
Porffor.wasm.i32.store16(outPtr, padString.charCodeAt(i % padStringLen), 0, 4);
|
970
|
+
Porffor.wasm.i32.store16(outPtr, Porffor.wasm.i32.load16_u(Porffor.wasm`local.get ${padString}` + (i % padStringLen) * 2, 0, 4), 0, 4);
|
902
971
|
outPtr += 2;
|
903
972
|
}
|
904
973
|
out.length = targetLength;
|
@@ -925,7 +994,6 @@ export const __ByteString_prototype_padStart = (_this: bytestring, targetLength:
|
|
925
994
|
|
926
995
|
let outPtr: i32 = Porffor.wasm`local.get ${out}`;
|
927
996
|
let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
|
928
|
-
const padStringPtr: i32 = Porffor.wasm`local.get ${padString}`;
|
929
997
|
|
930
998
|
const len: i32 = _this.length;
|
931
999
|
|
@@ -943,8 +1011,7 @@ export const __ByteString_prototype_padStart = (_this: bytestring, targetLength:
|
|
943
1011
|
const padStringLen: i32 = padString.length;
|
944
1012
|
if (padStringLen > 0) {
|
945
1013
|
for (let i: i32 = 0; i < todo; i++) {
|
946
|
-
Porffor.wasm.i32.store8(outPtr++, Porffor.wasm.i32.load8_u(
|
947
|
-
// Porffor.wasm.i32.store8(outPtr++, padString.charCodeAt(i % padStringLen), 0, 4);
|
1014
|
+
Porffor.wasm.i32.store8(outPtr++, Porffor.wasm.i32.load8_u(Porffor.wasm`local.get ${padString}` + (i % padStringLen), 0, 4), 0, 4);
|
948
1015
|
}
|
949
1016
|
|
950
1017
|
out.length = targetLength;
|
@@ -967,7 +1034,6 @@ export const __String_prototype_padEnd = (_this: string, targetLength: number, p
|
|
967
1034
|
|
968
1035
|
let outPtr: i32 = Porffor.wasm`local.get ${out}`;
|
969
1036
|
let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
|
970
|
-
// const padStringPtr: i32 = Porffor.wasm`local.get ${padString}`;
|
971
1037
|
|
972
1038
|
const len: i32 = _this.length;
|
973
1039
|
|
@@ -995,8 +1061,7 @@ export const __String_prototype_padEnd = (_this: string, targetLength: number, p
|
|
995
1061
|
const padStringLen: i32 = padString.length;
|
996
1062
|
if (padStringLen > 0) {
|
997
1063
|
for (let i: i32 = 0; i < todo; i++) {
|
998
|
-
|
999
|
-
Porffor.wasm.i32.store16(outPtr, padString.charCodeAt(i % padStringLen), 0, 4);
|
1064
|
+
Porffor.wasm.i32.store16(outPtr, Porffor.wasm.i32.load16_u(Porffor.wasm`local.get ${padString}` + (i % padStringLen) * 2, 0, 4), 0, 4);
|
1000
1065
|
outPtr += 2;
|
1001
1066
|
}
|
1002
1067
|
out.length = targetLength;
|
@@ -1014,7 +1079,6 @@ export const __ByteString_prototype_padEnd = (_this: bytestring, targetLength: n
|
|
1014
1079
|
|
1015
1080
|
let outPtr: i32 = Porffor.wasm`local.get ${out}`;
|
1016
1081
|
let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
|
1017
|
-
const padStringPtr: i32 = Porffor.wasm`local.get ${padString}`;
|
1018
1082
|
|
1019
1083
|
const len: i32 = _this.length;
|
1020
1084
|
|
@@ -1038,8 +1102,7 @@ export const __ByteString_prototype_padEnd = (_this: bytestring, targetLength: n
|
|
1038
1102
|
const padStringLen: i32 = padString.length;
|
1039
1103
|
if (padStringLen > 0) {
|
1040
1104
|
for (let i: i32 = 0; i < todo; i++) {
|
1041
|
-
Porffor.wasm.i32.store8(outPtr++, Porffor.wasm.i32.load8_u(
|
1042
|
-
// Porffor.wasm.i32.store8(outPtr++, padString.charCodeAt(i % padStringLen), 0, 4);
|
1105
|
+
Porffor.wasm.i32.store8(outPtr++, Porffor.wasm.i32.load8_u(Porffor.wasm`local.get ${padString}` + (i % padStringLen), 0, 4), 0, 4);
|
1043
1106
|
}
|
1044
1107
|
|
1045
1108
|
out.length = targetLength;
|
@@ -103,4 +103,23 @@ export const __String_fromCharCode = (...codes: any[]): bytestring|string => {
|
|
103
103
|
}
|
104
104
|
|
105
105
|
return out;
|
106
|
+
};
|
107
|
+
|
108
|
+
// in f64 file as returns NaN which returns 0 in i32
|
109
|
+
export const __String_prototype_charCodeAt = (_this: string, index: number) => {
|
110
|
+
const len: i32 = _this.length;
|
111
|
+
|
112
|
+
index |= 0;
|
113
|
+
if (Porffor.fastOr(index < 0, index >= len)) return NaN;
|
114
|
+
|
115
|
+
return Porffor.wasm.i32.load16_u(Porffor.wasm`local.get ${_this}` + index * 2, 0, 4);
|
116
|
+
};
|
117
|
+
|
118
|
+
export const __ByteString_prototype_charCodeAt = (_this: bytestring, index: number) => {
|
119
|
+
const len: i32 = _this.length;
|
120
|
+
|
121
|
+
index |= 0;
|
122
|
+
if (Porffor.fastOr(index < 0, index >= len)) return NaN;
|
123
|
+
|
124
|
+
return Porffor.wasm.i32.load8_u(Porffor.wasm`local.get ${_this}` + index, 0, 4);
|
106
125
|
};
|