porffor 0.17.0-f43ba190c โ 0.18.3
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/README.md +10 -9
- package/bf +0 -0
- package/compiler/2c.js +98 -15
- package/compiler/assemble.js +19 -4
- package/compiler/builtins/array.ts +102 -9
- package/compiler/builtins/date.ts +104 -106
- package/compiler/builtins/error.js +2 -5
- package/compiler/builtins/set.ts +4 -5
- package/compiler/builtins/string_f64.ts +4 -6
- package/compiler/builtins/symbol.ts +2 -1
- package/compiler/builtins/typedarray.js +58 -6
- package/compiler/builtins/z_ecma262.ts +1 -0
- package/compiler/builtins.js +13 -2
- package/compiler/codegen.js +486 -127
- package/compiler/cyclone.js +36 -0
- package/compiler/decompile.js +2 -2
- package/compiler/generated_builtins.js +2714 -713
- package/compiler/index.js +1 -0
- package/compiler/opt.js +3 -5
- package/compiler/precompile.js +4 -2
- package/compiler/prototype.js +0 -69
- package/package.json +1 -1
- package/rhemyn/README.md +7 -4
- package/rhemyn/compile.js +170 -76
- package/runner/index.js +3 -2
- package/runner/repl.js +1 -2
- package/runner/version.js +0 -12
package/README.md
CHANGED
@@ -148,41 +148,42 @@ These include some early (stage 1/0) and/or dead (last commit years ago) proposa
|
|
148
148
|
- Array constructor (`Array(5)`, `new Array(1, 2, 3)`)
|
149
149
|
- Labelled statements (`foo: while (...)`)
|
150
150
|
- `do...while` loops
|
151
|
+
- Optional parameters (`(foo = 'bar') => { ... }`)
|
151
152
|
|
152
153
|
### Built-ins
|
153
154
|
|
154
155
|
- `NaN` and `Infinity`
|
155
156
|
- `isNaN()` and `isFinite()`
|
156
157
|
- Most of `Number` (`MAX_VALUE`, `MIN_VALUE`, `MAX_SAFE_INTEGER`, `MIN_SAFE_INTEGER`, `POSITIVE_INFINITY`, `NEGATIVE_INFINITY`, `EPSILON`, `NaN`, `isNaN`, `isFinite`, `isInteger`, `isSafeInteger`)
|
157
|
-
-
|
158
|
+
- Most `Math` funcs (`sqrt`, `abs`, `floor`, `sign`, `round`, `trunc`, `clz32`, `fround`, `random`, `exp`, `log`, `log2`, `log10`, `pow`, `expm1`, `log1p`, `sqrt`, `cbrt`, `hypot`, `sin`, `cos`, `tan`, `sinh`, `cosh`, `tanh`, `asinh`, `acosh`, `atanh`, `asin`, `acos`, `atan`, `atan2`)
|
158
159
|
- Basic `globalThis` support
|
159
160
|
- Basic `Boolean` and `Number`
|
160
161
|
- Basic `eval` for literals
|
161
162
|
- `Math.random()` using self-made xorshift128+ PRNG
|
162
163
|
- Some of `performance` (`now()`, `timeOrigin`)
|
163
|
-
-
|
164
|
-
-
|
165
|
-
- Most of `String.prototype` (`at`, `charAt`, `charCodeAt`, `toUpperCase`, `toLowerCase`, `startsWith`, `endsWith`, `indexOf`, `lastIndexOf`, `includes`, `padStart`, `padEnd`, `substring`, `substr`, `slice`, `trimStart`, `trimEnd`, `trim`, `toString`, `big`, `blink`, `bold`, `fixed`, `italics`, `small`, `strike`, `sub`, `sup`, `trimLeft`, `trimRight`, )
|
164
|
+
- Most of `Array.prototype` (`at`, `push`, `pop`, `shift`, `fill`, `slice`, `indexOf`, `lastIndexOf`, `includes`, `with`, `reverse`, `toReversed`, `forEach`, `filter`, `map`, `find`, `findLast`, `findIndex`, `findLastIndex`, `every`, `some`, `reduce`, `reduceRight`, `join`, `toString`)
|
165
|
+
- Most of `Array` (`of`, `isArray`)
|
166
|
+
- Most of `String.prototype` (`at`, `charAt`, `charCodeAt`, `toUpperCase`, `toLowerCase`, `startsWith`, `endsWith`, `indexOf`, `lastIndexOf`, `includes`, `padStart`, `padEnd`, `substring`, `substr`, `slice`, `trimStart`, `trimEnd`, `trim`, `toString`, `big`, `blink`, `bold`, `fixed`, `italics`, `small`, `strike`, `sub`, `sup`, `trimLeft`, `trimRight`, `trim`)
|
166
167
|
- Some of `crypto` (`randomUUID`)
|
167
168
|
- `escape`
|
168
169
|
- `btoa`
|
169
170
|
- Most of `Number.prototype` (`toString`, `toFixed`, `toExponential`)
|
170
171
|
- `parseInt`
|
171
172
|
- Spec-compliant `Date`
|
173
|
+
- WIP typed arrays (`Uint8Array`, `Int32Array`, etc)
|
172
174
|
|
173
175
|
### Custom
|
174
176
|
|
175
177
|
- Supports i32, i64, and f64 for valtypes
|
176
|
-
- Start of a SIMD api (docs needed)
|
177
178
|
- Intrinsic functions (see below)
|
178
179
|
- Inlining wasm via ``asm`...``\` "macro"
|
179
180
|
|
180
181
|
## Versioning
|
181
|
-
Porffor uses a unique versioning system, here's an example: `0.
|
182
|
+
Porffor uses a unique versioning system, here's an example: `0.18.2+2aa3f0589`. Let's break it down:
|
182
183
|
1. `0` - major, always `0` as Porffor is not ready yet
|
183
|
-
2. `
|
184
|
-
3. `
|
185
|
-
4. `
|
184
|
+
2. `18` - minor, total Test262 pass percentage (floored to nearest int)
|
185
|
+
3. `2` - micro, build number for that minor (incremented each publish/git push)
|
186
|
+
4. `2aa3f0589` - commit hash
|
186
187
|
|
187
188
|
## Performance
|
188
189
|
*For the features it supports most of the time*, Porffor is *blazingly fast* compared to most interpreters and common engines running without JIT. For those with JIT, it is usually slower by default, but can catch up with compiler arguments and typed input, even more so when compiling to native binaries.
|
package/bf
ADDED
Binary file
|
package/compiler/2c.js
CHANGED
@@ -171,9 +171,6 @@ const removeBrackets = str => {
|
|
171
171
|
};
|
172
172
|
|
173
173
|
export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
174
|
-
// fix declaring order for c
|
175
|
-
funcs.reverse();
|
176
|
-
|
177
174
|
const invOperatorOpcode = Object.values(operatorOpcode).reduce((acc, x) => {
|
178
175
|
for (const k in x) {
|
179
176
|
acc[x[k]] = k;
|
@@ -201,7 +198,7 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
201
198
|
|
202
199
|
includes.set('stdint.h', true);
|
203
200
|
|
204
|
-
|
201
|
+
globalThis.out = ``;
|
205
202
|
|
206
203
|
for (const x in globals) {
|
207
204
|
const g = globals[x];
|
@@ -231,15 +228,12 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
231
228
|
|
232
229
|
if (out) out += '\n';
|
233
230
|
|
234
|
-
|
235
|
-
let brDepth = 0;
|
236
|
-
const line = (str, semi = true) => out += `${' '.repeat((depth + brDepth) * 2)}${str}${semi ? ';' : ''}\n`;
|
231
|
+
const line = (str, semi = true) => out += `${str}${semi ? ';' : ''}\n`;
|
237
232
|
const lines = lines => {
|
238
233
|
for (const x of lines) {
|
239
|
-
out +=
|
234
|
+
out += x + '\n';
|
240
235
|
}
|
241
236
|
};
|
242
|
-
|
243
237
|
const platformSpecific = (win, unix, add = true) => {
|
244
238
|
let tmp = '';
|
245
239
|
|
@@ -268,11 +262,46 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
268
262
|
|
269
263
|
let brId = 0;
|
270
264
|
|
271
|
-
|
272
|
-
|
273
|
-
|
265
|
+
const cified = new Set();
|
266
|
+
const cify = f => {
|
267
|
+
let out = '';
|
268
|
+
|
269
|
+
let depth = 1;
|
270
|
+
let brDepth = 0;
|
271
|
+
const line = (str, semi = true) => out += `${' '.repeat((depth + brDepth) * 2)}${str}${semi ? ';' : ''}\n`;
|
272
|
+
const lines = lines => {
|
273
|
+
for (const x of lines) {
|
274
|
+
out += `${' '.repeat((depth + brDepth) * 2)}${x}\n`;
|
275
|
+
}
|
276
|
+
};
|
277
|
+
const platformSpecific = (win, unix, add = true) => {
|
278
|
+
let tmp = '';
|
279
|
+
|
280
|
+
if (win) {
|
281
|
+
if (add) out += '#ifdef _WIN32\n';
|
282
|
+
else tmp += '#ifdef _WIN32\n';
|
283
|
+
|
284
|
+
if (add) lines(win.split('\n'));
|
285
|
+
else tmp += win + (win.endsWith('\n') ? '' : '\n');
|
286
|
+
}
|
287
|
+
|
288
|
+
if (unix) {
|
289
|
+
if (add) out += (win ? '#else' : '#ifndef _WIN32') + '\n';
|
290
|
+
else tmp += (win ? '#else' : '#ifndef _WIN32') + '\n';
|
291
|
+
|
292
|
+
if (add) lines(unix.split('\n'));
|
293
|
+
else tmp += unix + (unix.endsWith('\n') ? '' : '\n');
|
294
|
+
}
|
295
|
+
|
296
|
+
if (win || unix)
|
297
|
+
if (add) out += '#endif\n';
|
298
|
+
else tmp += '#endif\n';
|
299
|
+
|
300
|
+
return tmp;
|
301
|
+
};
|
274
302
|
|
275
303
|
let retTmpId = 0;
|
304
|
+
let tmpId = 0;
|
276
305
|
|
277
306
|
const invLocals = inv(f.locals, x => x.idx);
|
278
307
|
|
@@ -598,6 +627,11 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
|
|
598
627
|
break;
|
599
628
|
}
|
600
629
|
|
630
|
+
if (!cified.has(func.name) && func.name !== f.name) {
|
631
|
+
cify(func);
|
632
|
+
cified.add(func.name);
|
633
|
+
}
|
634
|
+
|
601
635
|
let args = [];
|
602
636
|
for (let j = 0; j < func.params.length; j++) args.unshift(removeBrackets(vals.pop()));
|
603
637
|
|
@@ -663,6 +697,53 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
|
|
663
697
|
break;
|
664
698
|
}
|
665
699
|
|
700
|
+
case Opcodes.f64_abs: {
|
701
|
+
break;
|
702
|
+
}
|
703
|
+
case Opcodes.f64_neg: {
|
704
|
+
break;
|
705
|
+
}
|
706
|
+
|
707
|
+
case Opcodes.f64_ceil: {
|
708
|
+
break;
|
709
|
+
}
|
710
|
+
case Opcodes.f64_floor: {
|
711
|
+
break;
|
712
|
+
}
|
713
|
+
case Opcodes.f64_trunc: {
|
714
|
+
break;
|
715
|
+
}
|
716
|
+
case Opcodes.f64_nearest: {
|
717
|
+
break;
|
718
|
+
}
|
719
|
+
|
720
|
+
case Opcodes.f64_sqrt: {
|
721
|
+
break;
|
722
|
+
}
|
723
|
+
case Opcodes.f64_min: {
|
724
|
+
const b = vals.pop();
|
725
|
+
const a = vals.pop();
|
726
|
+
|
727
|
+
const id = tmpId++;
|
728
|
+
line(`const f64 _tmp${id}a = ${a}`);
|
729
|
+
line(`const f64 _tmp${id}b = ${b}`);
|
730
|
+
vals.push(`(_tmp${id}a > _tmp${id}b ? _tmp${id}b : _tmp${id}a)`);
|
731
|
+
break;
|
732
|
+
}
|
733
|
+
case Opcodes.f64_max: {
|
734
|
+
const b = vals.pop();
|
735
|
+
const a = vals.pop();
|
736
|
+
|
737
|
+
const id = tmpId++;
|
738
|
+
line(`const f64 _tmp${id}a = ${a}`);
|
739
|
+
line(`const f64 _tmp${id}b = ${b}`);
|
740
|
+
vals.push(`(_tmp${id}a > _tmp${id}b ? _tmp${id}a : _tmp${id}b)`);
|
741
|
+
break;
|
742
|
+
}
|
743
|
+
case Opcodes.f64_copysign: {
|
744
|
+
break;
|
745
|
+
}
|
746
|
+
|
666
747
|
default:
|
667
748
|
if (CMemFuncs[i[0]]) {
|
668
749
|
const name = invOpcodes[i[0]];
|
@@ -698,12 +779,14 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
|
|
698
779
|
}
|
699
780
|
|
700
781
|
out += '}\n\n';
|
701
|
-
}
|
702
782
|
|
703
|
-
|
783
|
+
globalThis.out = globalThis.out + out;
|
784
|
+
};
|
785
|
+
|
786
|
+
cify(funcs.find(x => x.name === 'main'));
|
704
787
|
|
705
788
|
const makeIncludes = includes => [...includes.keys()].map(x => `#include <${x}>\n`).join('');
|
706
789
|
out = platformSpecific(makeIncludes(winIncludes), makeIncludes(unixIncludes), false) + '\n' + makeIncludes(includes) + '\n' + alwaysPreface + [...prepend.values()].join('\n') + '\n\n' + out;
|
707
790
|
|
708
|
-
return out.trim();
|
791
|
+
return `// generated by porffor ${globalThis.version ?? '0.17.0'}\n` + out.trim();
|
709
792
|
};
|
package/compiler/assemble.js
CHANGED
@@ -82,7 +82,17 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
82
82
|
params.push(valtypeBinary, Valtype.i32);
|
83
83
|
}
|
84
84
|
|
85
|
-
|
85
|
+
if (inst.at(-1) === 'constr') {
|
86
|
+
inst.pop();
|
87
|
+
params.unshift(Valtype.i32);
|
88
|
+
}
|
89
|
+
|
90
|
+
let returns = [ valtypeBinary, Valtype.i32 ];
|
91
|
+
if (inst.at(-1) === 'no_type_return') {
|
92
|
+
inst.pop();
|
93
|
+
returns = [ valtypeBinary ];
|
94
|
+
}
|
95
|
+
|
86
96
|
inst[1] = getType(params, returns);
|
87
97
|
}
|
88
98
|
}
|
@@ -116,16 +126,21 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
116
126
|
] ])
|
117
127
|
);
|
118
128
|
|
119
|
-
if (pages.has('func
|
120
|
-
// generate func
|
129
|
+
if (pages.has('func lut') && !data.addedFuncArgcLut) {
|
130
|
+
// generate func lut data
|
121
131
|
const bytes = [];
|
122
132
|
for (let i = 0; i < funcs.length; i++) {
|
123
133
|
const argc = Math.floor(funcs[i].params.length / 2);
|
124
134
|
bytes.push(argc % 256, (argc / 256 | 0) % 256);
|
135
|
+
|
136
|
+
let flags = 0b00000000; // 8 flag bits
|
137
|
+
if (funcs[i].returnType != null) flags |= 0b1;
|
138
|
+
if (funcs[i].constr) flags |= 0b10;
|
139
|
+
bytes.push(flags);
|
125
140
|
}
|
126
141
|
|
127
142
|
data.push({
|
128
|
-
offset: pages.get('func
|
143
|
+
offset: pages.get('func lut').ind * pageSize,
|
129
144
|
bytes
|
130
145
|
});
|
131
146
|
data.addedFuncArgcLut = true;
|
@@ -4,6 +4,7 @@ export const __Array_isArray = (x: unknown): boolean =>
|
|
4
4
|
// Porffor.wasm`local.get ${x+1}` == Porffor.TYPES.array;
|
5
5
|
Porffor.rawType(x) == Porffor.TYPES.array;
|
6
6
|
|
7
|
+
|
7
8
|
export const __Array_prototype_slice = (_this: any[], start: number, end: number) => {
|
8
9
|
const len: i32 = _this.length;
|
9
10
|
if (Porffor.rawType(end) == Porffor.TYPES.undefined) end = len;
|
@@ -22,7 +23,7 @@ export const __Array_prototype_slice = (_this: any[], start: number, end: number
|
|
22
23
|
}
|
23
24
|
if (end > len) end = len;
|
24
25
|
|
25
|
-
let out: any[] =
|
26
|
+
let out: any[] = Porffor.allocate();
|
26
27
|
|
27
28
|
if (start > end) return out;
|
28
29
|
|
@@ -42,10 +43,38 @@ export const __Array_prototype_slice = (_this: any[], start: number, end: number
|
|
42
43
|
}
|
43
44
|
|
44
45
|
out.length = end - start;
|
45
|
-
|
46
46
|
return out;
|
47
47
|
};
|
48
48
|
|
49
|
+
// @porf-typed-array
|
50
|
+
export const __Array_prototype_fill = (_this: any[], value: any, start: any, end: any) => {
|
51
|
+
const len: i32 = _this.length;
|
52
|
+
|
53
|
+
if (Porffor.rawType(start) == Porffor.TYPES.undefined) start = 0;
|
54
|
+
if (Porffor.rawType(end) == Porffor.TYPES.undefined) end = len;
|
55
|
+
|
56
|
+
start |= 0;
|
57
|
+
end |= 0;
|
58
|
+
|
59
|
+
if (start < 0) {
|
60
|
+
start = len + start;
|
61
|
+
if (start < 0) start = 0;
|
62
|
+
}
|
63
|
+
if (start > len) start = len;
|
64
|
+
if (end < 0) {
|
65
|
+
end = len + end;
|
66
|
+
if (end < 0) end = 0;
|
67
|
+
}
|
68
|
+
if (end > len) end = len;
|
69
|
+
|
70
|
+
for (let i: i32 = start; i < end; i++) {
|
71
|
+
_this[i] = value;
|
72
|
+
}
|
73
|
+
|
74
|
+
return _this;
|
75
|
+
};
|
76
|
+
|
77
|
+
// @porf-typed-array
|
49
78
|
export const __Array_prototype_indexOf = (_this: any[], searchElement: any, position: number) => {
|
50
79
|
const len: i32 = _this.length;
|
51
80
|
if (position > 0) {
|
@@ -60,6 +89,7 @@ export const __Array_prototype_indexOf = (_this: any[], searchElement: any, posi
|
|
60
89
|
return -1;
|
61
90
|
};
|
62
91
|
|
92
|
+
// @porf-typed-array
|
63
93
|
export const __Array_prototype_lastIndexOf = (_this: any[], searchElement: any, position: number) => {
|
64
94
|
const len: i32 = _this.length;
|
65
95
|
if (position > 0) {
|
@@ -74,6 +104,7 @@ export const __Array_prototype_lastIndexOf = (_this: any[], searchElement: any,
|
|
74
104
|
return -1;
|
75
105
|
};
|
76
106
|
|
107
|
+
// @porf-typed-array
|
77
108
|
export const __Array_prototype_includes = (_this: any[], searchElement: any, position: number) => {
|
78
109
|
const len: i32 = _this.length;
|
79
110
|
if (position > 0) {
|
@@ -88,6 +119,7 @@ export const __Array_prototype_includes = (_this: any[], searchElement: any, pos
|
|
88
119
|
return false;
|
89
120
|
};
|
90
121
|
|
122
|
+
// @porf-typed-array
|
91
123
|
export const __Array_prototype_with = (_this: any[], index: number, value: any) => {
|
92
124
|
const len: i32 = _this.length;
|
93
125
|
if (index < 0) {
|
@@ -101,8 +133,7 @@ export const __Array_prototype_with = (_this: any[], index: number, value: any)
|
|
101
133
|
throw new RangeError('Invalid index');
|
102
134
|
}
|
103
135
|
|
104
|
-
|
105
|
-
let out: any[] = [];
|
136
|
+
let out: any[] = Porffor.allocate();
|
106
137
|
|
107
138
|
Porffor.clone(_this, out);
|
108
139
|
|
@@ -111,6 +142,7 @@ export const __Array_prototype_with = (_this: any[], index: number, value: any)
|
|
111
142
|
return out;
|
112
143
|
};
|
113
144
|
|
145
|
+
// @porf-typed-array
|
114
146
|
export const __Array_prototype_reverse = (_this: any[]) => {
|
115
147
|
const len: i32 = _this.length;
|
116
148
|
|
@@ -126,14 +158,14 @@ export const __Array_prototype_reverse = (_this: any[]) => {
|
|
126
158
|
return _this;
|
127
159
|
};
|
128
160
|
|
129
|
-
//
|
161
|
+
// @porf-typed-array
|
130
162
|
export const __Array_prototype_toReversed = (_this: any[]) => {
|
131
163
|
const len: i32 = _this.length;
|
132
164
|
|
133
165
|
let start: i32 = 0;
|
134
166
|
let end: i32 = len - 1;
|
135
167
|
|
136
|
-
let out: any[] =
|
168
|
+
let out: any[] = Porffor.allocate();
|
137
169
|
out.length = len;
|
138
170
|
|
139
171
|
while (start < end) {
|
@@ -144,11 +176,13 @@ export const __Array_prototype_toReversed = (_this: any[]) => {
|
|
144
176
|
return out;
|
145
177
|
};
|
146
178
|
|
179
|
+
// @porf-typed-array
|
147
180
|
export const __Array_prototype_valueOf = (_this: any[]) => {
|
148
181
|
return _this;
|
149
182
|
};
|
150
183
|
|
151
184
|
|
185
|
+
// @porf-typed-array
|
152
186
|
export const __Array_prototype_forEach = (_this: any[], callbackFn: any) => {
|
153
187
|
const len: i32 = _this.length;
|
154
188
|
let i: i32 = 0;
|
@@ -157,22 +191,26 @@ export const __Array_prototype_forEach = (_this: any[], callbackFn: any) => {
|
|
157
191
|
}
|
158
192
|
};
|
159
193
|
|
194
|
+
// @porf-typed-array
|
160
195
|
export const __Array_prototype_filter = (_this: any[], callbackFn: any) => {
|
161
|
-
const out: any[] =
|
196
|
+
const out: any[] = Porffor.allocate();
|
162
197
|
|
163
198
|
const len: i32 = _this.length;
|
164
199
|
let i: i32 = 0;
|
200
|
+
let j: i32 = 0;
|
165
201
|
while (i < len) {
|
166
202
|
const el: any = _this[i];
|
167
|
-
if (Boolean(callbackFn(el, i++, _this))) out
|
203
|
+
if (Boolean(callbackFn(el, i++, _this))) out[j++] = el;
|
168
204
|
}
|
169
205
|
|
206
|
+
out.length = j;
|
170
207
|
return out;
|
171
208
|
};
|
172
209
|
|
210
|
+
// @porf-typed-array
|
173
211
|
export const __Array_prototype_map = (_this: any[], callbackFn: any) => {
|
174
212
|
const len: i32 = _this.length;
|
175
|
-
const out: any[] =
|
213
|
+
const out: any[] = Porffor.allocate();
|
176
214
|
out.length = len;
|
177
215
|
|
178
216
|
let i: i32 = 0;
|
@@ -183,6 +221,7 @@ export const __Array_prototype_map = (_this: any[], callbackFn: any) => {
|
|
183
221
|
return out;
|
184
222
|
};
|
185
223
|
|
224
|
+
// @porf-typed-array
|
186
225
|
export const __Array_prototype_find = (_this: any[], callbackFn: any) => {
|
187
226
|
const len: i32 = _this.length;
|
188
227
|
let i: i32 = 0;
|
@@ -192,6 +231,7 @@ export const __Array_prototype_find = (_this: any[], callbackFn: any) => {
|
|
192
231
|
}
|
193
232
|
};
|
194
233
|
|
234
|
+
// @porf-typed-array
|
195
235
|
export const __Array_prototype_findLast = (_this: any[], callbackFn: any) => {
|
196
236
|
let i: i32 = _this.length;
|
197
237
|
while (i > 0) {
|
@@ -200,6 +240,7 @@ export const __Array_prototype_findLast = (_this: any[], callbackFn: any) => {
|
|
200
240
|
}
|
201
241
|
};
|
202
242
|
|
243
|
+
// @porf-typed-array
|
203
244
|
export const __Array_prototype_findIndex = (_this: any[], callbackFn: any) => {
|
204
245
|
const len: i32 = _this.length;
|
205
246
|
let i: i32 = 0;
|
@@ -208,6 +249,7 @@ export const __Array_prototype_findIndex = (_this: any[], callbackFn: any) => {
|
|
208
249
|
}
|
209
250
|
};
|
210
251
|
|
252
|
+
// @porf-typed-array
|
211
253
|
export const __Array_prototype_findLastIndex = (_this: any[], callbackFn: any) => {
|
212
254
|
let i: i32 = _this.length;
|
213
255
|
while (i > 0) {
|
@@ -215,6 +257,7 @@ export const __Array_prototype_findLastIndex = (_this: any[], callbackFn: any) =
|
|
215
257
|
}
|
216
258
|
};
|
217
259
|
|
260
|
+
// @porf-typed-array
|
218
261
|
export const __Array_prototype_every = (_this: any[], callbackFn: any) => {
|
219
262
|
const len: i32 = _this.length;
|
220
263
|
let i: i32 = 0;
|
@@ -225,6 +268,7 @@ export const __Array_prototype_every = (_this: any[], callbackFn: any) => {
|
|
225
268
|
return true;
|
226
269
|
};
|
227
270
|
|
271
|
+
// @porf-typed-array
|
228
272
|
export const __Array_prototype_some = (_this: any[], callbackFn: any) => {
|
229
273
|
const len: i32 = _this.length;
|
230
274
|
let i: i32 = 0;
|
@@ -235,6 +279,7 @@ export const __Array_prototype_some = (_this: any[], callbackFn: any) => {
|
|
235
279
|
return false;
|
236
280
|
};
|
237
281
|
|
282
|
+
// @porf-typed-array
|
238
283
|
export const __Array_prototype_reduce = (_this: any[], callbackFn: any, initialValue: any) => {
|
239
284
|
let acc: any = initialValue ?? _this[0];
|
240
285
|
|
@@ -247,6 +292,7 @@ export const __Array_prototype_reduce = (_this: any[], callbackFn: any, initialV
|
|
247
292
|
return acc;
|
248
293
|
};
|
249
294
|
|
295
|
+
// @porf-typed-array
|
250
296
|
export const __Array_prototype_reduceRight = (_this: any[], callbackFn: any, initialValue: any) => {
|
251
297
|
const len: i32 = _this.length;
|
252
298
|
let acc: any = initialValue ?? _this[len - 1];
|
@@ -259,6 +305,52 @@ export const __Array_prototype_reduceRight = (_this: any[], callbackFn: any, ini
|
|
259
305
|
return acc;
|
260
306
|
};
|
261
307
|
|
308
|
+
// @porf-typed-array
|
309
|
+
export const __Array_prototype_sort = (_this: any[], callbackFn: any) => {
|
310
|
+
// todo: default callbackFn
|
311
|
+
|
312
|
+
// insertion sort, i guess
|
313
|
+
const len: i32 = _this.length;
|
314
|
+
for (let i: i32 = 0; i < len; i++) {
|
315
|
+
const x: any = _this[i];
|
316
|
+
let j: i32 = i;
|
317
|
+
while (j > 0) {
|
318
|
+
const y: any = _this[j - 1];
|
319
|
+
|
320
|
+
// 23.1.3.30.2 CompareArrayElements (x, y, comparefn)
|
321
|
+
// https://tc39.es/ecma262/#sec-comparearrayelements
|
322
|
+
const xt: i32 = Porffor.rawType(x);
|
323
|
+
const yt: i32 = Porffor.rawType(y);
|
324
|
+
let v: number;
|
325
|
+
|
326
|
+
// 1. If x and y are both undefined, return +0๐ฝ.
|
327
|
+
if (xt == Porffor.TYPES.undefined && yt == Porffor.TYPES.undefined) v = 0;
|
328
|
+
// 2. If x is undefined, return 1๐ฝ.
|
329
|
+
else if (xt == Porffor.TYPES.undefined) v = 1;
|
330
|
+
// 3. If y is undefined, return -1๐ฝ.
|
331
|
+
else if (yt == Porffor.TYPES.undefined) v = -1;
|
332
|
+
else {
|
333
|
+
// 4. If comparefn is not undefined, then
|
334
|
+
// a. Let v be ? ToNumber(? Call(comparefn, undefined, ยซ x, y ยป)).
|
335
|
+
v = callbackFn(x, y);
|
336
|
+
|
337
|
+
// b. If v is NaN, return +0๐ฝ.
|
338
|
+
// if (Number.isNaN(v)) v = 0;
|
339
|
+
|
340
|
+
// c. Return v.
|
341
|
+
}
|
342
|
+
|
343
|
+
if (v >= 0) break;
|
344
|
+
_this[j--] = y;
|
345
|
+
}
|
346
|
+
|
347
|
+
_this[j] = x;
|
348
|
+
}
|
349
|
+
|
350
|
+
return _this;
|
351
|
+
};
|
352
|
+
|
353
|
+
// @porf-typed-array
|
262
354
|
export const __Array_prototype_toString = (_this: any[]) => {
|
263
355
|
// todo: this is bytestring only!
|
264
356
|
|
@@ -283,6 +375,7 @@ export const __Array_prototype_toString = (_this: any[]) => {
|
|
283
375
|
return out;
|
284
376
|
};
|
285
377
|
|
378
|
+
// @porf-typed-array
|
286
379
|
export const __Array_prototype_join = (_this: any[], _separator: any) => {
|
287
380
|
// todo: this is bytestring only!
|
288
381
|
// todo/perf: optimize single char separators
|