porffor 0.55.28 → 0.55.31
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/compiler/builtins/__internal_object.ts +1 -1
- package/compiler/builtins/error.js +11 -15
- package/compiler/builtins_precompiled.js +1476 -1467
- package/compiler/codegen.js +17 -5
- package/compiler/types.js +8 -10
- package/compiler/wrap.js +1 -2
- package/package.json +1 -1
- package/r.cjs +252 -3
- package/runner/index.js +1 -1
package/compiler/codegen.js
CHANGED
@@ -3,7 +3,7 @@ import { number, ieee754_binary64, signedLEB128, unsignedLEB128, encodeVector, r
|
|
3
3
|
import { operatorOpcode } from './expression.js';
|
4
4
|
import { BuiltinFuncs, BuiltinVars, importedFuncs, NULL, UNDEFINED } from './builtins.js';
|
5
5
|
import { PrototypeFuncs } from './prototype.js';
|
6
|
-
import { TYPES, TYPE_FLAGS, TYPE_NAMES
|
6
|
+
import { TYPES, TYPE_FLAGS, TYPE_NAMES } from './types.js';
|
7
7
|
import * as Rhemyn from '../rhemyn/compile.js';
|
8
8
|
import parse from './parse.js';
|
9
9
|
import { log } from './log.js';
|
@@ -1505,7 +1505,18 @@ const setType = (scope, name, type, noInfer = false) => {
|
|
1505
1505
|
};
|
1506
1506
|
|
1507
1507
|
const getLastType = scope => {
|
1508
|
-
if (!scope.locals['#last_type']) return [
|
1508
|
+
if (!scope.locals['#last_type']) return [
|
1509
|
+
[ null, () => {
|
1510
|
+
if (scope.locals['#last_type']) {
|
1511
|
+
scope.gotLastType = true;
|
1512
|
+
return [
|
1513
|
+
[ Opcodes.local_get, localTmp(scope, '#last_type', Valtype.i32) ]
|
1514
|
+
];
|
1515
|
+
}
|
1516
|
+
|
1517
|
+
return [ number(TYPES.number, Valtype.i32) ];
|
1518
|
+
} ]
|
1519
|
+
];
|
1509
1520
|
|
1510
1521
|
scope.gotLastType = true;
|
1511
1522
|
return [
|
@@ -1664,7 +1675,7 @@ const getNodeType = (scope, node) => {
|
|
1664
1675
|
|
1665
1676
|
const objectKnownType = knownType(scope, getNodeType(scope, node.object));
|
1666
1677
|
if (objectKnownType != null) {
|
1667
|
-
if (name === 'length' &&
|
1678
|
+
if (name === 'length' && (objectKnownType & TYPE_FLAGS.length) !== 0) return TYPES.number;
|
1668
1679
|
|
1669
1680
|
if (node.computed) {
|
1670
1681
|
if (objectKnownType === TYPES.string) return TYPES.string;
|
@@ -3653,7 +3664,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3653
3664
|
|
3654
3665
|
const type = getNodeType(scope, decl.left.object);
|
3655
3666
|
const known = knownType(scope, type);
|
3656
|
-
if (known != null &&
|
3667
|
+
if (known != null && (known & TYPE_FLAGS.length) !== 0) return [
|
3657
3668
|
...out,
|
3658
3669
|
...optional([ Opcodes.local_tee, pointerTmp ]),
|
3659
3670
|
|
@@ -5678,7 +5689,7 @@ const generateMember = (scope, decl, _global, _name) => {
|
|
5678
5689
|
|
5679
5690
|
const type = getNodeType(scope, object);
|
5680
5691
|
const known = knownType(scope, type);
|
5681
|
-
if (known != null &&
|
5692
|
+
if (known != null && (known & TYPE_FLAGS.length) !== 0) return [
|
5682
5693
|
...out,
|
5683
5694
|
|
5684
5695
|
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
@@ -6655,6 +6666,7 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
|
|
6655
6666
|
if (typedInput && decl.returnType) {
|
6656
6667
|
const { type } = extractTypeAnnotation(decl.returnType);
|
6657
6668
|
if (type != null) {
|
6669
|
+
typeUsed(func, type);
|
6658
6670
|
func.returnType = type;
|
6659
6671
|
func.returns = func.returnType === TYPES.undefined && !func.async && !func.generator ? [] : [ valtypeBinary ];
|
6660
6672
|
}
|
package/compiler/types.js
CHANGED
@@ -30,10 +30,7 @@ export const TYPE_NAMES = {
|
|
30
30
|
[TYPES.bigint]: 'BigInt'
|
31
31
|
};
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
export const INTERNAL_TYPE_BASE = 0x10;
|
36
|
-
let internalTypeIndex = INTERNAL_TYPE_BASE;
|
33
|
+
let internalTypeIndex = TYPES.object + 1;
|
37
34
|
const registerInternalType = (name, flags = [], overrideType = undefined) => {
|
38
35
|
let n = overrideType ?? internalTypeIndex++;
|
39
36
|
|
@@ -72,12 +69,13 @@ registerInternalType('BooleanObject');
|
|
72
69
|
registerInternalType('NumberObject');
|
73
70
|
registerInternalType('StringObject');
|
74
71
|
|
75
|
-
for (const x of [ '', 'Aggregate', 'Type', 'Reference', 'Syntax', 'Range', 'Eval', 'URI', 'Test262', 'Todo' ])
|
76
|
-
registerInternalType(`${x}Error`);
|
77
|
-
|
78
72
|
registerInternalType('__Porffor_Generator');
|
79
73
|
registerInternalType('__Porffor_AsyncGenerator');
|
80
74
|
|
75
|
+
// from here, remapped object types only
|
76
|
+
for (const x of [ '', 'Aggregate', 'Type', 'Reference', 'Syntax', 'Range', 'Eval', 'URI', 'Test262' ])
|
77
|
+
registerInternalType(`${x}Error`);
|
78
|
+
|
81
79
|
if (Prefs.largestTypes) {
|
82
80
|
const typeKeys = Object.keys(TYPES);
|
83
81
|
const typeVals = Object.values(TYPES);
|
@@ -88,11 +86,11 @@ if (Prefs.largestTypes) {
|
|
88
86
|
return [ val, key ];
|
89
87
|
};
|
90
88
|
|
91
|
-
const unflag = val => val & 0b00111111;
|
92
|
-
|
93
89
|
const logType = (label, val, key) => console.log(`${label} ${key} - ${val} (0x${val.toString(16)}, 0b${val.toString(2).padStart(8, '0')})`);
|
94
90
|
|
95
|
-
|
91
|
+
const largestUnflagged = largestType(typeVals.map(x => x & 0b00111111), typeKeys);
|
92
|
+
logType(`largest type: `, ...largestUnflagged);
|
96
93
|
logType(`largest type w/ flags:`, ...largestType(typeVals, typeKeys));
|
94
|
+
console.log('types left:', 0b00111111 - largestUnflagged[0]);
|
97
95
|
console.log();
|
98
96
|
}
|
package/compiler/wrap.js
CHANGED
@@ -311,8 +311,7 @@ ${flags & 0b0001 ? ` get func idx: ${get}
|
|
311
311
|
case TYPES.rangeerror:
|
312
312
|
case TYPES.evalerror:
|
313
313
|
case TYPES.urierror:
|
314
|
-
case TYPES.test262error:
|
315
|
-
case TYPES.todoerror: {
|
314
|
+
case TYPES.test262error: {
|
316
315
|
const obj = porfToJSValue({ memory, funcs, pages }, value, TYPES.object);
|
317
316
|
const err = new (globalThis[TYPE_NAMES[type]] ?? Error)(obj.message);
|
318
317
|
|
package/package.json
CHANGED
package/r.cjs
CHANGED
@@ -1,8 +1,257 @@
|
|
1
|
-
function
|
2
|
-
|
1
|
+
Foo.prototype.baz = function baz() {};
|
2
|
+
|
3
|
+
function Foo() {
|
4
|
+
this.bar = 1;
|
3
5
|
}
|
4
6
|
|
5
|
-
|
7
|
+
Foo.prototype.bar = function bar() {};
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
// var EQUAL = 1;
|
12
|
+
// var NOT_EQUAL = -1;
|
13
|
+
// var UNKNOWN = 0;
|
14
|
+
|
15
|
+
// function setCache(cache, left, right, result) {
|
16
|
+
// var otherCache;
|
17
|
+
|
18
|
+
// otherCache = cache.get(left);
|
19
|
+
// if (!otherCache) cache.set(left, otherCache = new Map());
|
20
|
+
// otherCache.set(right, result);
|
21
|
+
|
22
|
+
// otherCache = cache.get(right);
|
23
|
+
// if (!otherCache) cache.set(right, otherCache = new Map());
|
24
|
+
// otherCache.set(left, result);
|
25
|
+
// }
|
26
|
+
|
27
|
+
// function getCache(cache, left, right) {
|
28
|
+
// var otherCache;
|
29
|
+
// var result;
|
30
|
+
|
31
|
+
// otherCache = cache.get(left);
|
32
|
+
// result = otherCache && otherCache.get(right);
|
33
|
+
// if (result) return result;
|
34
|
+
|
35
|
+
// otherCache = cache.get(right);
|
36
|
+
// result = otherCache && otherCache.get(left);
|
37
|
+
// if (result) return result;
|
38
|
+
|
39
|
+
// return UNKNOWN;
|
40
|
+
// }
|
41
|
+
|
42
|
+
// function cacheComparison(a, b, compare, cache) {
|
43
|
+
// var result = compare(a, b, cache);
|
44
|
+
// if (cache && (result === EQUAL || result === NOT_EQUAL)) {
|
45
|
+
// setCache(cache, a, b, result);
|
46
|
+
// }
|
47
|
+
// return result;
|
48
|
+
// }
|
49
|
+
|
50
|
+
// function isBoxed(value) {
|
51
|
+
// return value instanceof String
|
52
|
+
// || value instanceof Number
|
53
|
+
// || value instanceof Boolean
|
54
|
+
// || value instanceof Symbol;
|
55
|
+
// }
|
56
|
+
|
57
|
+
// function fail() {
|
58
|
+
// return NOT_EQUAL;
|
59
|
+
// }
|
60
|
+
|
61
|
+
// function compareIf(a, b, test, compare, cache) {
|
62
|
+
// return !test(a)
|
63
|
+
// ? !test(b) ? UNKNOWN : NOT_EQUAL
|
64
|
+
// : !test(b) ? NOT_EQUAL : cacheComparison(a, b, compare, cache);
|
65
|
+
// }
|
66
|
+
|
67
|
+
// function compareEquality(a, b, cache) {
|
68
|
+
// return compareIf(a, b, isOptional, compareOptionality)
|
69
|
+
// || compareIf(a, b, isPrimitiveEquatable, comparePrimitiveEquality)
|
70
|
+
// || compareIf(a, b, isObjectEquatable, compareObjectEquality, cache)
|
71
|
+
// || NOT_EQUAL;
|
72
|
+
// }
|
73
|
+
|
74
|
+
// function tryCompareStrictEquality(a, b) {
|
75
|
+
// return a === b ? EQUAL : UNKNOWN;
|
76
|
+
// }
|
77
|
+
|
78
|
+
// function tryCompareTypeOfEquality(a, b) {
|
79
|
+
// return typeof a !== typeof b ? NOT_EQUAL : UNKNOWN;
|
80
|
+
// }
|
81
|
+
|
82
|
+
// function tryCompareToStringTagEquality(a, b) {
|
83
|
+
// var aTag = Symbol.toStringTag in a ? a[Symbol.toStringTag] : undefined;
|
84
|
+
// var bTag = Symbol.toStringTag in b ? b[Symbol.toStringTag] : undefined;
|
85
|
+
// return aTag !== bTag ? NOT_EQUAL : UNKNOWN;
|
86
|
+
// }
|
87
|
+
|
88
|
+
// function isOptional(value) {
|
89
|
+
// return value === undefined
|
90
|
+
// || value === null;
|
91
|
+
// }
|
92
|
+
|
93
|
+
// function compareOptionality(a, b) {
|
94
|
+
// return tryCompareStrictEquality(a, b)
|
95
|
+
// || NOT_EQUAL;
|
96
|
+
// }
|
97
|
+
|
98
|
+
// function isPrimitiveEquatable(value) {
|
99
|
+
// switch (typeof value) {
|
100
|
+
// case 'string':
|
101
|
+
// case 'number':
|
102
|
+
// case 'boolean':
|
103
|
+
// case 'symbol':
|
104
|
+
// return true;
|
105
|
+
// default:
|
106
|
+
// return isBoxed(value);
|
107
|
+
// }
|
108
|
+
// }
|
109
|
+
|
110
|
+
// function comparePrimitiveEquality(a, b) {
|
111
|
+
// if (isBoxed(a)) a = a.valueOf();
|
112
|
+
// if (isBoxed(b)) b = b.valueOf();
|
113
|
+
|
114
|
+
// return tryCompareStrictEquality(a, b)
|
115
|
+
// || tryCompareTypeOfEquality(a, b)
|
116
|
+
// || compareIf(a, b, isNaNEquatable, compareNaNEquality)
|
117
|
+
// || NOT_EQUAL;
|
118
|
+
// }
|
119
|
+
|
120
|
+
// function isNaNEquatable(value) {
|
121
|
+
// return typeof value === 'number';
|
122
|
+
// }
|
123
|
+
|
124
|
+
// function compareNaNEquality(a, b) {
|
125
|
+
// return isNaN(a) && isNaN(b) ? EQUAL : NOT_EQUAL;
|
126
|
+
// }
|
127
|
+
|
128
|
+
// function isObjectEquatable(value) {
|
129
|
+
// return typeof value === 'object';
|
130
|
+
// }
|
131
|
+
|
132
|
+
// function compareObjectEquality(a, b, cache) {
|
133
|
+
// if (!cache) cache = new Map();
|
134
|
+
|
135
|
+
// return getCache(cache, a, b)
|
136
|
+
// || setCache(cache, a, b, EQUAL) // consider equal for now
|
137
|
+
// || cacheComparison(a, b, tryCompareStrictEquality, cache)
|
138
|
+
// || cacheComparison(a, b, tryCompareToStringTagEquality, cache)
|
139
|
+
// || compareIf(a, b, isValueOfEquatable, compareValueOfEquality)
|
140
|
+
// || compareIf(a, b, isToStringEquatable, compareToStringEquality)
|
141
|
+
// || compareIf(a, b, isArrayLikeEquatable, compareArrayLikeEquality, cache)
|
142
|
+
// || compareIf(a, b, isStructurallyEquatable, compareStructuralEquality, cache)
|
143
|
+
// || compareIf(a, b, isIterableEquatable, compareIterableEquality, cache)
|
144
|
+
// || cacheComparison(a, b, fail, cache);
|
145
|
+
// }
|
146
|
+
|
147
|
+
// function isValueOfEquatable(value) {
|
148
|
+
// return value instanceof Date;
|
149
|
+
// }
|
150
|
+
|
151
|
+
// function compareValueOfEquality(a, b) {
|
152
|
+
// return compareIf(a.valueOf(), b.valueOf(), isPrimitiveEquatable, comparePrimitiveEquality)
|
153
|
+
// || NOT_EQUAL;
|
154
|
+
// }
|
155
|
+
|
156
|
+
// function isToStringEquatable(value) {
|
157
|
+
// return value instanceof RegExp;
|
158
|
+
// }
|
159
|
+
|
160
|
+
// function compareToStringEquality(a, b) {
|
161
|
+
// return compareIf(a.toString(), b.toString(), isPrimitiveEquatable, comparePrimitiveEquality)
|
162
|
+
// || NOT_EQUAL;
|
163
|
+
// }
|
164
|
+
|
165
|
+
// function isArrayLikeEquatable(value) {
|
166
|
+
// return Array.isArray(value)
|
167
|
+
// || value instanceof Uint8Array
|
168
|
+
// || value instanceof Uint8ClampedArray
|
169
|
+
// || value instanceof Uint16Array
|
170
|
+
// || value instanceof Uint32Array
|
171
|
+
// || value instanceof Int8Array
|
172
|
+
// || value instanceof Int16Array
|
173
|
+
// || value instanceof Int32Array
|
174
|
+
// || value instanceof Float32Array
|
175
|
+
// || value instanceof Float64Array;
|
176
|
+
// }
|
177
|
+
|
178
|
+
// function compareArrayLikeEquality(a, b, cache) {
|
179
|
+
// if (a.length !== b.length) return NOT_EQUAL;
|
180
|
+
// for (var i = 0; i < a.length; i++) {
|
181
|
+
// if (compareEquality(a[i], b[i], cache) === NOT_EQUAL) {
|
182
|
+
// return NOT_EQUAL;
|
183
|
+
// }
|
184
|
+
// }
|
185
|
+
// return EQUAL;
|
186
|
+
// }
|
187
|
+
|
188
|
+
// function isStructurallyEquatable(value) {
|
189
|
+
// return !(value instanceof Promise // only comparable by reference
|
190
|
+
// || value instanceof WeakMap // only comparable by reference
|
191
|
+
// || value instanceof WeakSet // only comparable by reference
|
192
|
+
// || value instanceof Map // comparable via @@iterator
|
193
|
+
// || value instanceof Set); // comparable via @@iterator
|
194
|
+
// }
|
195
|
+
|
196
|
+
// function compareStructuralEquality(a, b, cache) {
|
197
|
+
// var aKeys = [];
|
198
|
+
// for (var key in a) aKeys.push(key);
|
199
|
+
|
200
|
+
// var bKeys = [];
|
201
|
+
// for (var key in b) bKeys.push(key);
|
202
|
+
|
203
|
+
// if (aKeys.length !== bKeys.length) {
|
204
|
+
// return NOT_EQUAL;
|
205
|
+
// }
|
206
|
+
|
207
|
+
// aKeys.sort();
|
208
|
+
// bKeys.sort();
|
209
|
+
|
210
|
+
// for (var i = 0; i < aKeys.length; i++) {
|
211
|
+
// var aKey = aKeys[i];
|
212
|
+
// var bKey = bKeys[i];
|
213
|
+
// if (compareEquality(aKey, bKey, cache) === NOT_EQUAL) {
|
214
|
+
// return NOT_EQUAL;
|
215
|
+
// }
|
216
|
+
// if (compareEquality(a[aKey], b[bKey], cache) === NOT_EQUAL) {
|
217
|
+
// return NOT_EQUAL;
|
218
|
+
// }
|
219
|
+
// }
|
220
|
+
|
221
|
+
// return EQUAL;
|
222
|
+
// }
|
223
|
+
|
224
|
+
// // hack: do iterables via for..of
|
225
|
+
// function isIterableEquatable(value) {
|
226
|
+
// try {
|
227
|
+
// for (const _ of value) { break; }
|
228
|
+
// return true;
|
229
|
+
// } catch {
|
230
|
+
// return false;
|
231
|
+
// }
|
232
|
+
// }
|
233
|
+
|
234
|
+
// function compareIterableEquality(a, b, cache) {
|
235
|
+
// let aValues = [];
|
236
|
+
// for (const x of a) aValues.push(x);
|
237
|
+
|
238
|
+
// let bValues = [];
|
239
|
+
// for (const x of b) bValues.push(x);
|
240
|
+
|
241
|
+
// return compareArrayLikeEquality(aValues, bValues, cache);
|
242
|
+
// }
|
243
|
+
|
244
|
+
// var __assert_deepEqual__compare = (a, b) => {
|
245
|
+
// return compareEquality(a, b) === EQUAL;
|
246
|
+
// };
|
247
|
+
|
248
|
+
// var __assert_deepEqual = (actual, expected) => {
|
249
|
+
// if (!assert.deepEqual._compare(actual, expected)) {
|
250
|
+
// throw new Test262Error('assert.deepEqual failed');
|
251
|
+
// }
|
252
|
+
// };
|
253
|
+
|
254
|
+
// __assert_deepEqual([], []);
|
6
255
|
|
7
256
|
// let x = {};
|
8
257
|
// x.__proto__ = { wow() { console.log(0); } };
|