porffor 0.14.0-33cb5e44b โ 0.14.0-3905158d3
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/CONTRIBUTING.md +5 -1
- package/asur/index.js +1 -1
- package/compiler/assemble.js +14 -0
- package/compiler/builtins/array.ts +82 -4
- package/compiler/builtins/boolean.ts +1 -1
- package/compiler/builtins/error.js +22 -0
- package/compiler/builtins/math.ts +408 -0
- package/compiler/builtins/set.ts +5 -6
- package/compiler/builtins/symbol.ts +1 -1
- package/compiler/builtins.js +10 -6
- package/compiler/codegen.js +495 -252
- package/compiler/generated_builtins.js +566 -135
- package/compiler/precompile.js +4 -3
- package/compiler/prefs.js +1 -1
- package/compiler/prototype.js +180 -157
- package/compiler/wrap.js +66 -37
- package/package.json +1 -1
- package/porffor_tmp.c +152 -0
- package/runner/index.js +1 -1
- package/runner/repl.js +18 -2
package/CONTRIBUTING.md
CHANGED
@@ -231,7 +231,11 @@ builtins/tostring_number: impl radix
|
|
231
231
|
|
232
232
|
Make sure you have Test262 cloned already **inside of `test262/`** (`git clone https://github.com/tc39/test262.git test262/test262`) and run `npm install` inside `test262/` too.
|
233
233
|
|
234
|
-
Run `node test262` to run all the tests and get an output of total overall test results.
|
234
|
+
Run `node test262` to run all the tests and get an output of total overall test results.
|
235
|
+
|
236
|
+
Warning: this will consume 1-6GB of memory and ~90% of all CPU cores while running (depending on thread count), it should take 15-120s depending on machine. You can specify how many threads with `--threads=N`, it will use the number of CPU threads by default.
|
237
|
+
|
238
|
+
The main thing you want to pay attention to is the emoji summary (lol):
|
235
239
|
```
|
236
240
|
๐งช 50005 | ๐ค 7007 (-89) | โ 1914 (-32) | ๐ 13904 (-61) | ๐ 23477 (-120) | โฐ 2 | ๐ 2073 (+302) | ๐ฅ 1628
|
237
241
|
```
|
package/asur/index.js
CHANGED
@@ -1155,7 +1155,7 @@ if (bc.porfFunc && paused && op) {
|
|
1155
1155
|
switch (byg(
|
1156
1156
|
paused,
|
1157
1157
|
funcLines[currentFunc] + currentLine,
|
1158
|
-
'\x1b[1masur\x1b[22m: ' + callStack.join(' -> ') + (parents.length > 1 ? \` | \${parents.slice(1).map(x => invOpcodes[x.opcode]).join(' -> ')}\` : ''),
|
1158
|
+
'\x1b[1masur debugger\x1b[22m: ' + callStack.join(' -> ') + (parents.length > 1 ? \` | \${parents.slice(1).map(x => invOpcodes[x.opcode]).join(' -> ')}\` : ''),
|
1159
1159
|
[
|
1160
1160
|
{
|
1161
1161
|
x: termWidth - 1 - width - 6,
|
package/compiler/assemble.js
CHANGED
@@ -116,6 +116,20 @@ export default (funcs, globals, tags, pages, data, flags) => {
|
|
116
116
|
] ])
|
117
117
|
);
|
118
118
|
|
119
|
+
if (pages.has('func argc lut')) {
|
120
|
+
// generate func argc lut data
|
121
|
+
const bytes = [];
|
122
|
+
for (let i = 0; i < funcs.length; i++) {
|
123
|
+
const argc = Math.floor(funcs[i].params.length / 2);
|
124
|
+
bytes.push(argc % 256, (argc / 256 | 0) % 256);
|
125
|
+
}
|
126
|
+
|
127
|
+
data.push({
|
128
|
+
offset: pages.get('func argc lut').ind * pageSize,
|
129
|
+
bytes
|
130
|
+
});
|
131
|
+
}
|
132
|
+
|
119
133
|
// const t0 = performance.now();
|
120
134
|
|
121
135
|
// specially optimized assembly for globals as this version is much (>5x) faster than traditional createSection()
|
@@ -27,14 +27,16 @@ export const __Array_prototype_slice = (_this: any[], start: number, end: number
|
|
27
27
|
let outPtr: i32 = Porffor.wasm`local.get ${out}`;
|
28
28
|
let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
|
29
29
|
|
30
|
-
const thisPtrEnd: i32 = thisPtr + end *
|
30
|
+
const thisPtrEnd: i32 = thisPtr + end * 9;
|
31
31
|
|
32
|
-
thisPtr += start *
|
32
|
+
thisPtr += start * 9;
|
33
33
|
|
34
34
|
while (thisPtr < thisPtrEnd) {
|
35
35
|
Porffor.wasm.f64.store(outPtr, Porffor.wasm.f64.load(thisPtr, 0, 4), 0, 4);
|
36
|
-
thisPtr
|
37
|
-
|
36
|
+
Porffor.wasm.i32.store8(outPtr + 8, Porffor.wasm.i32.load8_u(thisPtr + 8, 0, 4), 0, 4);
|
37
|
+
|
38
|
+
thisPtr += 9;
|
39
|
+
outPtr += 9;
|
38
40
|
}
|
39
41
|
|
40
42
|
out.length = end - start;
|
@@ -142,4 +144,80 @@ export const __Array_prototype_toReversed = (_this: any[]) => {
|
|
142
144
|
|
143
145
|
export const __Array_prototype_valueOf = (_this: any[]) => {
|
144
146
|
return _this;
|
147
|
+
};
|
148
|
+
|
149
|
+
|
150
|
+
export const __Array_prototype_forEach = (_this: any[], callbackFn: any) => {
|
151
|
+
const len: i32 = _this.length;
|
152
|
+
let i: i32 = 0;
|
153
|
+
while (i < len) {
|
154
|
+
callbackFn(_this[i], i++, _this);
|
155
|
+
}
|
156
|
+
};
|
157
|
+
|
158
|
+
export const __Array_prototype_filter = (_this: any[], callbackFn: any) => {
|
159
|
+
const out: any[] = [];
|
160
|
+
|
161
|
+
const len: i32 = _this.length;
|
162
|
+
let i: i32 = 0;
|
163
|
+
while (i < len) {
|
164
|
+
const el: any = _this[i];
|
165
|
+
if (callbackFn(el, i++, _this)) out.push(el);
|
166
|
+
}
|
167
|
+
|
168
|
+
return out;
|
169
|
+
};
|
170
|
+
|
171
|
+
export const __Array_prototype_map = (_this: any[], callbackFn: any) => {
|
172
|
+
const out: any[] = [];
|
173
|
+
|
174
|
+
const len: i32 = _this.length;
|
175
|
+
let i: i32 = 0;
|
176
|
+
while (i < len) {
|
177
|
+
out.push(callbackFn(_this[i], i++, _this));
|
178
|
+
}
|
179
|
+
|
180
|
+
return out;
|
181
|
+
};
|
182
|
+
|
183
|
+
export const __Array_prototype_find = (_this: any[], callbackFn: any) => {
|
184
|
+
const len: i32 = _this.length;
|
185
|
+
let i: i32 = 0;
|
186
|
+
while (i < len) {
|
187
|
+
const el: any = _this[i];
|
188
|
+
if (callbackFn(el, i++, _this)) return el;
|
189
|
+
}
|
190
|
+
};
|
191
|
+
|
192
|
+
export const __Array_prototype_findLast = (_this: any[], callbackFn: any) => {
|
193
|
+
let i: i32 = _this.length;
|
194
|
+
while (i > 0) {
|
195
|
+
const el: any = _this[--i];
|
196
|
+
if (callbackFn(el, i, _this)) return el;
|
197
|
+
}
|
198
|
+
};
|
199
|
+
|
200
|
+
export const __Array_prototype_findIndex = (_this: any[], callbackFn: any) => {
|
201
|
+
const len: i32 = _this.length;
|
202
|
+
let i: i32 = 0;
|
203
|
+
while (i < len) {
|
204
|
+
if (callbackFn(_this[i], i++, _this)) return i;
|
205
|
+
}
|
206
|
+
};
|
207
|
+
|
208
|
+
export const __Array_prototype_findLastIndex = (_this: any[], callbackFn: any) => {
|
209
|
+
let i: i32 = _this.length;
|
210
|
+
while (i > 0) {
|
211
|
+
if (callbackFn(_this[--i], i, _this)) return i;
|
212
|
+
}
|
213
|
+
};
|
214
|
+
|
215
|
+
export const __Array_prototype_every = (_this: any[], callbackFn: any) => {
|
216
|
+
const len: i32 = _this.length;
|
217
|
+
let i: i32 = 0;
|
218
|
+
while (i < len) {
|
219
|
+
if (!callbackFn(_this[i], i++, _this)) return false;
|
220
|
+
}
|
221
|
+
|
222
|
+
return true;
|
145
223
|
};
|
@@ -4,7 +4,7 @@ export const __Boolean_prototype_toString = (_this: boolean) => {
|
|
4
4
|
// 1. Let b be ? ThisBooleanValue(this value).
|
5
5
|
// 2. If b is true, return "true"; else return "false".
|
6
6
|
let out: bytestring = '';
|
7
|
-
if (_this) out = 'true';
|
7
|
+
if (_this == true) out = 'true';
|
8
8
|
else out = 'false';
|
9
9
|
|
10
10
|
return out;
|
@@ -0,0 +1,22 @@
|
|
1
|
+
export default () => {
|
2
|
+
let out = '';
|
3
|
+
|
4
|
+
const error = name => out += `export const ${name} = (message: bytestring) => {
|
5
|
+
return {};
|
6
|
+
};
|
7
|
+
|
8
|
+
export const ${name}$constructor = (message: bytestring) => {
|
9
|
+
return {};
|
10
|
+
};`;
|
11
|
+
|
12
|
+
error('Error');
|
13
|
+
error('AggregateError');
|
14
|
+
error('TypeError');
|
15
|
+
error('ReferenceError');
|
16
|
+
error('SyntaxError');
|
17
|
+
error('RangeError');
|
18
|
+
error('EvalError');
|
19
|
+
error('URIError');
|
20
|
+
|
21
|
+
return out;
|
22
|
+
};
|
@@ -0,0 +1,408 @@
|
|
1
|
+
// todo: use any and Number(x) in all these later
|
2
|
+
// todo: specify the rest of this file later
|
3
|
+
// todo/perf: make i32 variants later
|
4
|
+
// todo/perf: add a compiler pref for accuracy vs perf (epsilion?)
|
5
|
+
|
6
|
+
export const __Math_exp = (x: number): number => {
|
7
|
+
if (!Number.isFinite(x)) {
|
8
|
+
if (x == -Infinity) return 0;
|
9
|
+
return x;
|
10
|
+
}
|
11
|
+
|
12
|
+
if (x < 0) {
|
13
|
+
// exp(-x) = 1 / exp(+x)
|
14
|
+
return 1 / Math.exp(-x);
|
15
|
+
}
|
16
|
+
|
17
|
+
const k: number = Math.floor(x / Math.LN2);
|
18
|
+
const r: number = x - k * Math.LN2;
|
19
|
+
|
20
|
+
// Horner's method
|
21
|
+
let term: number = r;
|
22
|
+
let sum: number = 1 + r;
|
23
|
+
let i: number = 2;
|
24
|
+
|
25
|
+
while (Math.abs(term) > 1e-15) {
|
26
|
+
term *= r / i;
|
27
|
+
sum += term;
|
28
|
+
i++;
|
29
|
+
}
|
30
|
+
|
31
|
+
return sum * (1 << k);
|
32
|
+
};
|
33
|
+
|
34
|
+
export const __Math_log2 = (y: number): number => {
|
35
|
+
if (y <= 0) return NaN;
|
36
|
+
if (!Number.isFinite(y)) return y;
|
37
|
+
|
38
|
+
// approx using log knowledge
|
39
|
+
let x: number = y;
|
40
|
+
let exponent: number = 0;
|
41
|
+
|
42
|
+
while (x >= 2) {
|
43
|
+
x /= 2;
|
44
|
+
exponent++;
|
45
|
+
}
|
46
|
+
|
47
|
+
while (x < 1) {
|
48
|
+
x *= 2;
|
49
|
+
exponent--;
|
50
|
+
}
|
51
|
+
|
52
|
+
// 1 <= x < 2 -> 0 <= x < 1
|
53
|
+
x -= 1;
|
54
|
+
|
55
|
+
// refine with Newton-Raphson method
|
56
|
+
let delta: number;
|
57
|
+
do {
|
58
|
+
const e_x: number = Math.exp(x * Math.LN2);
|
59
|
+
delta = (e_x - y) / (e_x * Math.LN2);
|
60
|
+
x -= delta;
|
61
|
+
} while (Math.abs(delta) > 1e-15);
|
62
|
+
|
63
|
+
return x + exponent;
|
64
|
+
};
|
65
|
+
|
66
|
+
export const __Math_log = (y: number): number => {
|
67
|
+
if (y <= 0) {
|
68
|
+
if (y == 0) return -Infinity;
|
69
|
+
return NaN;
|
70
|
+
}
|
71
|
+
if (!Number.isFinite(y)) return y;
|
72
|
+
|
73
|
+
// guess using log knowledge
|
74
|
+
let x: number = y > 1 ? Math.log2(y) : 0;
|
75
|
+
|
76
|
+
// refine with Newton-Raphson method
|
77
|
+
let delta: number;
|
78
|
+
do {
|
79
|
+
const e_x: number = Math.exp(x);
|
80
|
+
delta = (e_x - y) / e_x;
|
81
|
+
x -= delta;
|
82
|
+
} while (Math.abs(delta) > 1e-15);
|
83
|
+
|
84
|
+
return x;
|
85
|
+
};
|
86
|
+
|
87
|
+
export const __Math_log10 = (x: number): number => {
|
88
|
+
if (x <= 0) {
|
89
|
+
if (x == 0) return -Infinity;
|
90
|
+
return NaN;
|
91
|
+
}
|
92
|
+
if (!Number.isFinite(x)) return x;
|
93
|
+
|
94
|
+
return Math.log(x) / Math.LN10;
|
95
|
+
};
|
96
|
+
|
97
|
+
// 21.3.2.26 Math.pow (base, exponent)
|
98
|
+
// https://tc39.es/ecma262/#sec-math.pow
|
99
|
+
export const __Math_pow = (base: number, exponent: number): number => {
|
100
|
+
// 1. Set base to ? ToNumber(base).
|
101
|
+
// 2. Set exponent to ? ToNumber(exponent).
|
102
|
+
// todo
|
103
|
+
|
104
|
+
// 3. Return Number::exponentiate(base, exponent).
|
105
|
+
|
106
|
+
// Number::exponentiate (base, exponent)
|
107
|
+
// https://tc39.es/ecma262/#sec-numeric-types-number-exponentiate
|
108
|
+
// 1. If exponent is NaN, return NaN.
|
109
|
+
if (Number.isNaN(exponent)) return NaN;
|
110
|
+
|
111
|
+
// 2. If exponent is either +0๐ฝ or -0๐ฝ, return 1๐ฝ.
|
112
|
+
if (exponent == 0) return 1;
|
113
|
+
|
114
|
+
if (!Number.isFinite(base)) {
|
115
|
+
// 3. If base is NaN, return NaN.
|
116
|
+
if (Number.isNaN(base)) return base;
|
117
|
+
|
118
|
+
// 4. If base is +โ๐ฝ, then
|
119
|
+
if (base == Infinity) {
|
120
|
+
// a. If exponent > +0๐ฝ, return +โ๐ฝ. Otherwise, return +0๐ฝ.
|
121
|
+
if (exponent > 0) return base;
|
122
|
+
return 0;
|
123
|
+
}
|
124
|
+
|
125
|
+
// 5. If base is -โ๐ฝ, then
|
126
|
+
const isOdd = exponent % 2 == 1;
|
127
|
+
|
128
|
+
// a. If exponent > +0๐ฝ, then
|
129
|
+
if (exponent > 0) {
|
130
|
+
// i. If exponent is an odd integral Number, return -โ๐ฝ. Otherwise, return +โ๐ฝ.
|
131
|
+
if (isOdd) return -Infinity;
|
132
|
+
return Infinity;
|
133
|
+
}
|
134
|
+
|
135
|
+
// b. Else,
|
136
|
+
// i. If exponent is an odd integral Number, return -0๐ฝ. Otherwise, return +0๐ฝ.
|
137
|
+
if (isOdd) return -0;
|
138
|
+
return 0;
|
139
|
+
}
|
140
|
+
|
141
|
+
if (base == 0) {
|
142
|
+
// 6. If base is +0๐ฝ, then
|
143
|
+
if (1 / base == Infinity) {
|
144
|
+
// a. If exponent > +0๐ฝ, return +0๐ฝ. Otherwise, return +โ๐ฝ.
|
145
|
+
if (exponent > 0) return 0;
|
146
|
+
return Infinity;
|
147
|
+
}
|
148
|
+
|
149
|
+
// 7. If base is -0๐ฝ, then
|
150
|
+
const isOdd = exponent % 2 == 1;
|
151
|
+
|
152
|
+
// a. If exponent > +0๐ฝ, then
|
153
|
+
if (exponent > 0) {
|
154
|
+
// i. If exponent is an odd integral Number, return -0๐ฝ. Otherwise, return +0๐ฝ.
|
155
|
+
if (isOdd) return -0;
|
156
|
+
return 0;
|
157
|
+
}
|
158
|
+
|
159
|
+
// b. Else,
|
160
|
+
// i. If exponent is an odd integral Number, return -โ๐ฝ. Otherwise, return +โ๐ฝ.
|
161
|
+
if (isOdd) return -Infinity;
|
162
|
+
return Infinity;
|
163
|
+
}
|
164
|
+
|
165
|
+
// 8. Assert: base is finite and is neither +0๐ฝ nor -0๐ฝ.
|
166
|
+
// todo
|
167
|
+
|
168
|
+
// 9. If exponent is +โ๐ฝ, then
|
169
|
+
if (exponent == Infinity) {
|
170
|
+
const abs = Math.abs(base);
|
171
|
+
|
172
|
+
// a. If abs(โ(base)) > 1, return +โ๐ฝ.
|
173
|
+
if (abs > 1) return Infinity;
|
174
|
+
|
175
|
+
// b. If abs(โ(base)) = 1, return NaN.
|
176
|
+
if (abs == 1) return NaN;
|
177
|
+
|
178
|
+
// c. If abs(โ(base)) < 1, return +0๐ฝ.
|
179
|
+
return 0;
|
180
|
+
}
|
181
|
+
|
182
|
+
// 10. If exponent is -โ๐ฝ, then
|
183
|
+
if (exponent == -Infinity) {
|
184
|
+
const abs = Math.abs(base);
|
185
|
+
|
186
|
+
// a. If abs(โ(base)) > 1, return +0๐ฝ.
|
187
|
+
if (abs > 1) return 0;
|
188
|
+
|
189
|
+
// b. If abs(โ(base)) = 1, return NaN.
|
190
|
+
if (abs == 1) return NaN;
|
191
|
+
|
192
|
+
// c. If abs(โ(base)) < 1, return +โ๐ฝ.
|
193
|
+
return Infinity;
|
194
|
+
}
|
195
|
+
|
196
|
+
// 11. Assert: exponent is finite and is neither +0๐ฝ nor -0๐ฝ.
|
197
|
+
// todo
|
198
|
+
|
199
|
+
// 12. If base < -0๐ฝ and exponent is not an integral Number, return NaN.
|
200
|
+
if (base < 0) if (!Number.isInteger(exponent)) return NaN;
|
201
|
+
|
202
|
+
// 13. Return an implementation-approximated Number value representing the result of raising โ(base) to the โ(exponent) power.
|
203
|
+
return Math.exp(exponent * Math.log(base));
|
204
|
+
};
|
205
|
+
|
206
|
+
|
207
|
+
export const __Math_expm1 = (x: number): number => {
|
208
|
+
if (!Number.isFinite(x)) {
|
209
|
+
if (x == -Infinity) return -1;
|
210
|
+
return x;
|
211
|
+
}
|
212
|
+
|
213
|
+
// use exp(x) - 1 for large x (perf)
|
214
|
+
if (Math.abs(x) > 1e-5) return Math.exp(x) - 1;
|
215
|
+
|
216
|
+
// Taylor series
|
217
|
+
let sum: number = x;
|
218
|
+
let term: number = x;
|
219
|
+
let i: number = 2;
|
220
|
+
|
221
|
+
while (Math.abs(term) > 1e-15) {
|
222
|
+
term *= x / i;
|
223
|
+
sum += term;
|
224
|
+
i++;
|
225
|
+
}
|
226
|
+
|
227
|
+
return sum;
|
228
|
+
};
|
229
|
+
|
230
|
+
export const __Math_log1p = (x: number): number => {
|
231
|
+
if (x == -1) return -Infinity; // log(0) = -inf
|
232
|
+
if (!Number.isFinite(x)) return x;
|
233
|
+
|
234
|
+
// use exp(x) - 1 for large x (perf)
|
235
|
+
if (Math.abs(x) > 1e-5) return Math.log(1 + x);
|
236
|
+
|
237
|
+
// Taylor series
|
238
|
+
let sum: number = 0;
|
239
|
+
let term: number = x;
|
240
|
+
let i: number = 2;
|
241
|
+
|
242
|
+
while (Math.abs(term) > 1e-15) {
|
243
|
+
term *= -x / i;
|
244
|
+
sum += term;
|
245
|
+
i++;
|
246
|
+
}
|
247
|
+
|
248
|
+
return sum;
|
249
|
+
};
|
250
|
+
|
251
|
+
|
252
|
+
export const __Math_sqrt = (y: number): number => {
|
253
|
+
if (y <= 0) {
|
254
|
+
if (y == 0) return 0;
|
255
|
+
return NaN;
|
256
|
+
}
|
257
|
+
if (!Number.isFinite(y)) return y;
|
258
|
+
|
259
|
+
// Babylonian method
|
260
|
+
let x: number = y;
|
261
|
+
let prev: number;
|
262
|
+
|
263
|
+
do {
|
264
|
+
prev = x;
|
265
|
+
x = 0.5 * (x + y / x);
|
266
|
+
} while (Math.abs(prev - x) > 1e-15);
|
267
|
+
|
268
|
+
return x;
|
269
|
+
};
|
270
|
+
|
271
|
+
export const __Math_cbrt = (y: number): number => {
|
272
|
+
if (y == 0) return 0; // cbrt(0) = 0
|
273
|
+
if (!Number.isFinite(y)) return y;
|
274
|
+
|
275
|
+
// Babylonian method
|
276
|
+
let x = Math.abs(y);
|
277
|
+
|
278
|
+
let prev: number;
|
279
|
+
|
280
|
+
do {
|
281
|
+
prev = x;
|
282
|
+
x = (2 * x + y / (x * x)) / 3;
|
283
|
+
} while (Math.abs(prev - x) > 1e-15);
|
284
|
+
|
285
|
+
return y < 0 ? -x : x;
|
286
|
+
};
|
287
|
+
|
288
|
+
|
289
|
+
// todo: varargs
|
290
|
+
export const __Math_hypot = (x: number, y: number): number => Math.sqrt(x * x + y * y);
|
291
|
+
|
292
|
+
export const __Math_sin = (x: number): number => {
|
293
|
+
// -inf <= x <= inf -> 0 <= x <= 2pi
|
294
|
+
const piX2: number = Math.PI * 2;
|
295
|
+
x %= piX2;
|
296
|
+
if (x < 0) x += piX2;
|
297
|
+
|
298
|
+
const x2: number = x * x;
|
299
|
+
|
300
|
+
return x * (
|
301
|
+
1 + x2 * (
|
302
|
+
-1.66666666666666307295e-1 + x2 * (
|
303
|
+
8.33333333332211858878e-3 + x2 * (
|
304
|
+
-1.98412698295895385996e-4 + x2 * (
|
305
|
+
2.75573136213857245213e-6 + x2 * (
|
306
|
+
-2.50507477628578072866e-8 + x2 * (
|
307
|
+
1.58962301576546568060e-10
|
308
|
+
)
|
309
|
+
)
|
310
|
+
)
|
311
|
+
)
|
312
|
+
)
|
313
|
+
)
|
314
|
+
);
|
315
|
+
|
316
|
+
// todo: investigate which is better (consider perf and accuracy)
|
317
|
+
// const x2 = x * x;
|
318
|
+
// const x4 = x2 * x2;
|
319
|
+
// const x6 = x4 * x2;
|
320
|
+
// const x8 = x4 * x4;
|
321
|
+
// const x10 = x6 * x4;
|
322
|
+
// const x12 = x6 * x6;
|
323
|
+
// const x14 = x12 * x2;
|
324
|
+
|
325
|
+
// return x * (
|
326
|
+
// 1 - x2 / 6 + x4 / 120 - x6 / 5040 + x8 / 362880 - x10 / 39916800 + x12 / 6227020800 - x14 / 1307674368000
|
327
|
+
// );
|
328
|
+
};
|
329
|
+
|
330
|
+
export const __Math_cos = (x: number): number => Math.sin(x - Math.PI / 2);
|
331
|
+
export const __Math_tan = (x: number): number => Math.sin(x) / Math.cos(x);
|
332
|
+
|
333
|
+
export const __Math_sinh = (x: number): number => (Math.exp(x) - Math.exp(-x)) / 2;
|
334
|
+
export const __Math_cosh = (x: number): number => (Math.exp(x) + Math.exp(-x)) / 2;
|
335
|
+
export const __Math_tanh = (x: number): number => Math.sinh(x) / Math.cosh(x);
|
336
|
+
|
337
|
+
|
338
|
+
export const __Math_asinh = (x: number): number => Math.log(x + Math.sqrt(x * x + 1));
|
339
|
+
export const __Math_acosh = (x: number): number => {
|
340
|
+
if (x < 1) return NaN;
|
341
|
+
return Math.log(x + Math.sqrt(x * x - 1));
|
342
|
+
};
|
343
|
+
export const __Math_atanh = (x: number): number => {
|
344
|
+
if (Math.abs(x) >= 1) return NaN;
|
345
|
+
return 0.5 * Math.log((1 + x) / (1 - x));
|
346
|
+
};
|
347
|
+
|
348
|
+
|
349
|
+
export const __Math_asin = (x: number): number => {
|
350
|
+
if (x <= -1) {
|
351
|
+
if (x == -1) return -Math.PI / 2;
|
352
|
+
return NaN;
|
353
|
+
}
|
354
|
+
if (x >= 1) {
|
355
|
+
if (x == 1) return Math.PI / 2;
|
356
|
+
return NaN;
|
357
|
+
}
|
358
|
+
|
359
|
+
// Taylor series
|
360
|
+
let sum: number = x;
|
361
|
+
let term: number = x;
|
362
|
+
let n: number = 1;
|
363
|
+
|
364
|
+
while (Math.abs(term) > 1e-15) {
|
365
|
+
term *= x * x * (2 * n - 1) * (2 * n - 1) / ((2 * n) * (2 * n + 1));
|
366
|
+
sum += term / (2 * n + 1);
|
367
|
+
n++;
|
368
|
+
}
|
369
|
+
|
370
|
+
return sum;
|
371
|
+
};
|
372
|
+
|
373
|
+
export const __Math_acos = (x: number): number => Math.asin(x) - Math.PI / 2;
|
374
|
+
|
375
|
+
export const __Math_atan = (x: number): number => {
|
376
|
+
if (x == Infinity) return Math.PI / 2
|
377
|
+
if (x == -Infinity) return -Math.PI / 2;
|
378
|
+
|
379
|
+
// Taylor series
|
380
|
+
let sum: number = x;
|
381
|
+
let term: number = x;
|
382
|
+
let n: number = 1;
|
383
|
+
|
384
|
+
while (Math.abs(term) > 1e-15) {
|
385
|
+
term *= -x * x * (2 * n - 1) / ((2 * n) * (2 * n + 1));
|
386
|
+
sum += term;
|
387
|
+
n++;
|
388
|
+
}
|
389
|
+
|
390
|
+
return sum;
|
391
|
+
};
|
392
|
+
|
393
|
+
export const __Math_atan2 = (y: number, x: number): number => {
|
394
|
+
if (x == 0) {
|
395
|
+
if (y > 0) return Math.PI / 2;
|
396
|
+
if (y < 0) return -Math.PI / 2;
|
397
|
+
|
398
|
+
return NaN;
|
399
|
+
}
|
400
|
+
|
401
|
+
const ratio = y / x;
|
402
|
+
if (x > 0) {
|
403
|
+
return Math.atan(ratio);
|
404
|
+
}
|
405
|
+
|
406
|
+
if (y >= 0) return Math.atan(ratio) + Math.PI;
|
407
|
+
return Math.atan(ratio) - Math.PI;
|
408
|
+
};
|
package/compiler/builtins/set.ts
CHANGED
@@ -56,14 +56,13 @@ i32.store8 0 12`;
|
|
56
56
|
};
|
57
57
|
|
58
58
|
|
59
|
-
|
60
|
-
export const __Set_prototype_size = (_this: Set) => {
|
59
|
+
export const __Set_prototype_size$get = (_this: Set) => {
|
61
60
|
return Porffor.wasm.i32.load(_this, 0, 0);
|
62
61
|
};
|
63
62
|
|
64
63
|
export const __Set_prototype_values = (_this: Set) => {
|
65
64
|
// todo: this should return an iterator not array
|
66
|
-
const size: number =
|
65
|
+
const size: number = Porffor.wasm.i32.load(_this, 0, 0);
|
67
66
|
|
68
67
|
const out: any[] = __Porffor_allocate();
|
69
68
|
for (let i: number = 0; i < size; i++) {
|
@@ -79,7 +78,7 @@ export const __Set_prototype_keys = (_this: Set) => {
|
|
79
78
|
};
|
80
79
|
|
81
80
|
export const __Set_prototype_has = (_this: Set, value: any) => {
|
82
|
-
const size: number =
|
81
|
+
const size: number = Porffor.wasm.i32.load(_this, 0, 0);
|
83
82
|
|
84
83
|
for (let i: number = 0; i < size; i++) {
|
85
84
|
if (__Porffor_set_read(_this, i) === value) return true;
|
@@ -89,7 +88,7 @@ export const __Set_prototype_has = (_this: Set, value: any) => {
|
|
89
88
|
};
|
90
89
|
|
91
90
|
export const __Set_prototype_add = (_this: Set, value: any) => {
|
92
|
-
const size: number =
|
91
|
+
const size: number = Porffor.wasm.i32.load(_this, 0, 0);
|
93
92
|
|
94
93
|
// check if already in set
|
95
94
|
for (let i: number = 0; i < size; i++) {
|
@@ -107,7 +106,7 @@ export const __Set_prototype_add = (_this: Set, value: any) => {
|
|
107
106
|
};
|
108
107
|
|
109
108
|
export const __Set_prototype_delete = (_this: Set, value: any) => {
|
110
|
-
const size: number =
|
109
|
+
const size: number = Porffor.wasm.i32.load(_this, 0, 0);
|
111
110
|
|
112
111
|
// check if already in set
|
113
112
|
for (let i: number = 0; i < size; i++) {
|
@@ -19,7 +19,7 @@ export const Symbol = (description: any): Symbol => {
|
|
19
19
|
};
|
20
20
|
|
21
21
|
// todo: this should be a getter somehow not a method
|
22
|
-
export const __Symbol_prototype_description = (_this: Symbol) => {
|
22
|
+
export const __Symbol_prototype_description$get = (_this: Symbol) => {
|
23
23
|
const description: bytestring = __Porffor_symbol_descStore(false,
|
24
24
|
Porffor.wasm`local.get ${_this}` - 1);
|
25
25
|
return description;
|
package/compiler/builtins.js
CHANGED
@@ -221,7 +221,7 @@ export const BuiltinFuncs = function() {
|
|
221
221
|
typedParams: true,
|
222
222
|
locals: [ Valtype.i32, Valtype.i32 ],
|
223
223
|
returns: [],
|
224
|
-
wasm: (scope, { typeSwitch }) => [
|
224
|
+
wasm: (scope, { typeSwitch, builtin }) => [
|
225
225
|
...typeSwitch(scope, [ [ Opcodes.local_get, 1 ] ], {
|
226
226
|
[TYPES.number]: [
|
227
227
|
[ Opcodes.local_get, 0 ],
|
@@ -317,7 +317,7 @@ export const BuiltinFuncs = function() {
|
|
317
317
|
|
318
318
|
// make end pointer
|
319
319
|
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
320
|
-
...number(ValtypeSize[valtype], Valtype.i32),
|
320
|
+
...number(ValtypeSize[valtype] + 1, Valtype.i32),
|
321
321
|
[ Opcodes.i32_mul ],
|
322
322
|
|
323
323
|
[ Opcodes.local_get, 2 ],
|
@@ -326,14 +326,18 @@ export const BuiltinFuncs = function() {
|
|
326
326
|
|
327
327
|
[ Opcodes.loop, Blocktype.void ],
|
328
328
|
|
329
|
-
// print current
|
329
|
+
// print current array element
|
330
330
|
[ Opcodes.local_get, 2 ],
|
331
|
-
[ Opcodes.load,
|
332
|
-
|
331
|
+
[ Opcodes.load, 0, ValtypeSize.i32 ],
|
332
|
+
|
333
|
+
[ Opcodes.local_get, 2 ],
|
334
|
+
[ Opcodes.i32_load8_u, 0, ValtypeSize.i32 + ValtypeSize[valtype] ],
|
335
|
+
|
336
|
+
[ Opcodes.call, builtin('__Porffor_print') ],
|
333
337
|
|
334
338
|
// increment pointer by sizeof valtype
|
335
339
|
[ Opcodes.local_get, 2 ],
|
336
|
-
...number(ValtypeSize[valtype], Valtype.i32),
|
340
|
+
...number(ValtypeSize[valtype] + 1, Valtype.i32),
|
337
341
|
[ Opcodes.i32_add ],
|
338
342
|
[ Opcodes.local_tee, 2 ],
|
339
343
|
|