porffor 0.14.0-4057a18e9 → 0.14.0-41dbb00ce
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 +1 -1
- package/compiler/assemble.js +12 -1
- package/compiler/builtins/boolean.ts +1 -1
- package/compiler/builtins/symbol.ts +61 -0
- package/compiler/builtins.js +4 -2
- package/compiler/codegen.js +101 -19
- package/compiler/generated_builtins.js +45 -0
- package/compiler/index.js +3 -8
- package/compiler/precompile.js +1 -1
- package/compiler/prefs.js +1 -1
- package/compiler/wrap.js +26 -8
- package/package.json +1 -1
package/README.md
CHANGED
@@ -191,7 +191,7 @@ These include some early (stage 1/0) and/or dead (last commit years ago) proposa
|
|
191
191
|
|
192
192
|
## Versioning
|
193
193
|
Porffor uses a unique versioning system, here's an example: `0.14.0-15cb49f07`. Let's break it down:
|
194
|
-
1. `0` - major, always `0` as Porffor is not ready yet
|
194
|
+
1. `0` - major, always `0` as Porffor is not ready yet
|
195
195
|
2. `14` - minor, total Test262 pass percentage (floored to nearest int)
|
196
196
|
3. `0` - micro, always `0` as unused
|
197
197
|
4. `15cb49f07` - commit hash
|
package/compiler/assemble.js
CHANGED
@@ -65,6 +65,7 @@ export default (funcs, globals, tags, pages, data, flags) => {
|
|
65
65
|
importFuncs = [...imports.values()];
|
66
66
|
|
67
67
|
// fix call indexes for non-imports
|
68
|
+
// also fix call_indirect types
|
68
69
|
const delta = importedFuncs.length - importFuncs.length;
|
69
70
|
for (const f of funcs) {
|
70
71
|
f.originalIndex = f.index;
|
@@ -74,6 +75,16 @@ export default (funcs, globals, tags, pages, data, flags) => {
|
|
74
75
|
if ((inst[0] === Opcodes.call || inst[0] === Opcodes.return_call) && inst[1] >= importedFuncs.length) {
|
75
76
|
inst[1] -= delta;
|
76
77
|
}
|
78
|
+
|
79
|
+
if (inst[0] === Opcodes.call_indirect) {
|
80
|
+
const params = [];
|
81
|
+
for (let i = 0; i < inst[1]; i++) {
|
82
|
+
params.push(valtypeBinary, Valtype.i32);
|
83
|
+
}
|
84
|
+
|
85
|
+
const returns = [ valtypeBinary, Valtype.i32 ];
|
86
|
+
inst[1] = getType(params, returns);
|
87
|
+
}
|
77
88
|
}
|
78
89
|
}
|
79
90
|
}
|
@@ -101,7 +112,7 @@ export default (funcs, globals, tags, pages, data, flags) => {
|
|
101
112
|
encodeVector([ [
|
102
113
|
0x00,
|
103
114
|
Opcodes.i32_const, 0, Opcodes.end,
|
104
|
-
encodeVector(funcs.map(x => x.index))
|
115
|
+
...encodeVector(funcs.map(x => x.index))
|
105
116
|
] ])
|
106
117
|
);
|
107
118
|
|
@@ -0,0 +1,61 @@
|
|
1
|
+
export const __Porffor_symbol_descStore = (op: boolean, value: any): any => {
|
2
|
+
const ptr: bytestring = '';
|
3
|
+
|
4
|
+
if (op) { // write
|
5
|
+
const size: number = Porffor.wasm.i32.load(ptr, 0, 0);
|
6
|
+
Porffor.wasm.i32.store(ptr, size + 1, 0, 0)
|
7
|
+
|
8
|
+
// reuse set internals to store description
|
9
|
+
__Porffor_set_write(ptr, size, value);
|
10
|
+
return size;
|
11
|
+
} else { // read
|
12
|
+
return __Porffor_set_read(ptr, value);
|
13
|
+
}
|
14
|
+
};
|
15
|
+
|
16
|
+
export const Symbol = (description: any): Symbol => {
|
17
|
+
// 1-based so always truthy as numeric value
|
18
|
+
return __Porffor_symbol_descStore(true, description) + 1;
|
19
|
+
};
|
20
|
+
|
21
|
+
// todo: this should be a getter somehow not a method
|
22
|
+
export const __Symbol_prototype_description = (_this: Symbol) => {
|
23
|
+
const description: bytestring = __Porffor_symbol_descStore(false,
|
24
|
+
Porffor.wasm`local.get ${_this}` - 1);
|
25
|
+
return description;
|
26
|
+
};
|
27
|
+
|
28
|
+
export const __Symbol_prototype_toString = (_this: Symbol) => {
|
29
|
+
let out: bytestring = '';
|
30
|
+
|
31
|
+
// Symbol(
|
32
|
+
Porffor.wasm.i32.store8(out, 83, 0, 4);
|
33
|
+
Porffor.wasm.i32.store8(out, 121, 0, 5);
|
34
|
+
Porffor.wasm.i32.store8(out, 109, 0, 6);
|
35
|
+
Porffor.wasm.i32.store8(out, 98, 0, 7);
|
36
|
+
Porffor.wasm.i32.store8(out, 111, 0, 8);
|
37
|
+
Porffor.wasm.i32.store8(out, 108, 0, 9);
|
38
|
+
Porffor.wasm.i32.store8(out, 40, 0, 10);
|
39
|
+
|
40
|
+
const description: bytestring = __Porffor_symbol_descStore(false,
|
41
|
+
Porffor.wasm`local.get ${_this}` - 1);
|
42
|
+
|
43
|
+
const descLen: i32 = description.length;
|
44
|
+
let outPtr: i32 = Porffor.wasm`local.get ${out}` + 7;
|
45
|
+
let descPtr: i32 = Porffor.wasm`local.get ${description}`;
|
46
|
+
const descPtrEnd: i32 = descPtr + descLen;
|
47
|
+
while (descPtr < descPtrEnd) {
|
48
|
+
Porffor.wasm.i32.store8(outPtr++, Porffor.wasm.i32.load8_u(descPtr++, 0, 4), 0, 4);
|
49
|
+
}
|
50
|
+
|
51
|
+
// )
|
52
|
+
Porffor.wasm.i32.store8(Porffor.wasm`local.get ${out}` + descLen, 41, 0, 11);
|
53
|
+
|
54
|
+
out.length = 8 + descLen;
|
55
|
+
|
56
|
+
return out;
|
57
|
+
};
|
58
|
+
|
59
|
+
export const __Symbol_prototype_valueOf = (_this: Symbol) => {
|
60
|
+
return _this;
|
61
|
+
};
|
package/compiler/builtins.js
CHANGED
@@ -198,7 +198,8 @@ export const BuiltinFuncs = function() {
|
|
198
198
|
returns: [ valtypeBinary ],
|
199
199
|
wasm: [
|
200
200
|
[ Opcodes.local_get, 0 ]
|
201
|
-
]
|
201
|
+
],
|
202
|
+
constr: true
|
202
203
|
};
|
203
204
|
|
204
205
|
// just return given (default 0) for (new) Object() as we somewhat supports object just not constructor
|
@@ -210,7 +211,8 @@ export const BuiltinFuncs = function() {
|
|
210
211
|
wasm: [
|
211
212
|
// [ Opcodes.local_get, 0 ]
|
212
213
|
...number(1)
|
213
|
-
]
|
214
|
+
],
|
215
|
+
constr: true
|
214
216
|
};
|
215
217
|
|
216
218
|
|
package/compiler/codegen.js
CHANGED
@@ -58,10 +58,11 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
|
|
58
58
|
|
59
59
|
case 'ArrowFunctionExpression':
|
60
60
|
case 'FunctionDeclaration':
|
61
|
+
case 'FunctionExpression':
|
61
62
|
const func = generateFunc(scope, decl);
|
62
63
|
|
63
64
|
if (decl.type.endsWith('Expression')) {
|
64
|
-
return number(func.index);
|
65
|
+
return number(func.index - importedFuncs.length);
|
65
66
|
}
|
66
67
|
|
67
68
|
return [];
|
@@ -187,7 +188,7 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
|
|
187
188
|
if (!Array.isArray(inst)) inst = [ inst ];
|
188
189
|
const immediates = asm.slice(1).map(x => {
|
189
190
|
const int = parseInt(x);
|
190
|
-
if (Number.isNaN(int)) return scope.locals[x]?.idx;
|
191
|
+
if (Number.isNaN(int)) return scope.locals[x]?.idx ?? globals[x].idx;
|
191
192
|
return int;
|
192
193
|
});
|
193
194
|
|
@@ -313,10 +314,10 @@ const generateIdent = (scope, decl) => {
|
|
313
314
|
|
314
315
|
if (local?.idx === undefined) {
|
315
316
|
// no local var with name
|
316
|
-
if (Object.hasOwn(importedFuncs, name)) return number(importedFuncs[name]);
|
317
|
-
if (Object.hasOwn(funcIndex, name)) return number(funcIndex[name]);
|
318
|
-
|
319
317
|
if (Object.hasOwn(globals, name)) return [ [ Opcodes.global_get, globals[name].idx ] ];
|
318
|
+
|
319
|
+
if (Object.hasOwn(importedFuncs, name)) return number(importedFuncs[name] - importedFuncs.length);
|
320
|
+
if (Object.hasOwn(funcIndex, name)) return number(funcIndex[name] - importedFuncs.length);
|
320
321
|
}
|
321
322
|
|
322
323
|
if (local?.idx === undefined && rawName.startsWith('__')) {
|
@@ -350,9 +351,7 @@ const generateReturn = (scope, decl) => {
|
|
350
351
|
|
351
352
|
return [
|
352
353
|
...generate(scope, decl.argument),
|
353
|
-
...(scope.returnType != null ? [] :
|
354
|
-
...getNodeType(scope, decl.argument)
|
355
|
-
]),
|
354
|
+
...(scope.returnType != null ? [] : getNodeType(scope, decl.argument)),
|
356
355
|
[ Opcodes.return ]
|
357
356
|
];
|
358
357
|
};
|
@@ -1450,6 +1449,10 @@ const countLeftover = wasm => {
|
|
1450
1449
|
} else count--;
|
1451
1450
|
if (func) count += func.returns.length;
|
1452
1451
|
}
|
1452
|
+
} else if (inst[0] === Opcodes.call_indirect) {
|
1453
|
+
count--; // funcidx
|
1454
|
+
count -= inst[1] * 2; // params * 2 (typed)
|
1455
|
+
count += 2; // fixed return (value, type)
|
1453
1456
|
} else count--;
|
1454
1457
|
|
1455
1458
|
// console.log(count, decompile([ inst ]).slice(0, -1));
|
@@ -1831,7 +1834,45 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1831
1834
|
}
|
1832
1835
|
|
1833
1836
|
if (idx === undefined) {
|
1834
|
-
if (scope.locals[name] !== undefined || globals[name] !== undefined || builtinVars[name] !== undefined)
|
1837
|
+
if (scope.locals[name] !== undefined || globals[name] !== undefined || builtinVars[name] !== undefined) {
|
1838
|
+
const [ local, global ] = lookupName(scope, name);
|
1839
|
+
if (!Prefs.indirectCalls || local == null) return internalThrow(scope, 'TypeError', `${unhackName(name)} is not a function`, true);
|
1840
|
+
|
1841
|
+
// todo: only works when:
|
1842
|
+
// 1. arg count matches arg count of function
|
1843
|
+
// 2. function uses typedParams and typedReturns
|
1844
|
+
|
1845
|
+
funcs.table = true;
|
1846
|
+
|
1847
|
+
let args = decl.arguments;
|
1848
|
+
let argWasm = [];
|
1849
|
+
|
1850
|
+
for (let i = 0; i < args.length; i++) {
|
1851
|
+
const arg = args[i];
|
1852
|
+
argWasm = argWasm.concat(generate(scope, arg));
|
1853
|
+
|
1854
|
+
if (valtypeBinary !== Valtype.i32 && (
|
1855
|
+
(builtinFuncs[name] && builtinFuncs[name].params[i * (typedParams ? 2 : 1)] === Valtype.i32) ||
|
1856
|
+
(importedFuncs[name] && name.startsWith('profile'))
|
1857
|
+
)) {
|
1858
|
+
argWasm.push(Opcodes.i32_to);
|
1859
|
+
}
|
1860
|
+
|
1861
|
+
argWasm = argWasm.concat(getNodeType(scope, arg));
|
1862
|
+
}
|
1863
|
+
|
1864
|
+
return typeSwitch(scope, getNodeType(scope, decl.callee), {
|
1865
|
+
[TYPES.function]: [
|
1866
|
+
...argWasm,
|
1867
|
+
[ global ? Opcodes.global_get : Opcodes.local_get, local.idx ],
|
1868
|
+
Opcodes.i32_to_u,
|
1869
|
+
[ Opcodes.call_indirect, args.length, 0 ],
|
1870
|
+
...setLastType(scope)
|
1871
|
+
],
|
1872
|
+
default: internalThrow(scope, 'TypeError', `${unhackName(name)} is not a function`, true)
|
1873
|
+
});
|
1874
|
+
}
|
1875
|
+
|
1835
1876
|
return internalThrow(scope, 'ReferenceError', `${unhackName(name)} is not defined`, true);
|
1836
1877
|
}
|
1837
1878
|
|
@@ -1860,11 +1901,16 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1860
1901
|
const arg = args[i];
|
1861
1902
|
out = out.concat(generate(scope, arg));
|
1862
1903
|
|
1863
|
-
if (
|
1864
|
-
|
1904
|
+
if (i >= paramCount) {
|
1905
|
+
// over param count of func, drop arg
|
1906
|
+
out.push([ Opcodes.drop ]);
|
1907
|
+
continue;
|
1865
1908
|
}
|
1866
1909
|
|
1867
|
-
if (
|
1910
|
+
if (valtypeBinary !== Valtype.i32 && (
|
1911
|
+
(builtinFuncs[name] && builtinFuncs[name].params[i * (typedParams ? 2 : 1)] === Valtype.i32) ||
|
1912
|
+
(importedFuncs[name] && name.startsWith('profile'))
|
1913
|
+
)) {
|
1868
1914
|
out.push(Opcodes.i32_to);
|
1869
1915
|
}
|
1870
1916
|
|
@@ -1909,6 +1955,11 @@ const generateNew = (scope, decl, _global, _name) => {
|
|
1909
1955
|
}, _global, _name);
|
1910
1956
|
}
|
1911
1957
|
|
1958
|
+
if (
|
1959
|
+
(builtinFuncs[name] && !builtinFuncs[name].constr) ||
|
1960
|
+
(internalConstrs[name] && builtinFuncs[name].notConstr)
|
1961
|
+
) return internalThrow(scope, 'TypeError', `${name} is not a constructor`);
|
1962
|
+
|
1912
1963
|
if (!builtinFuncs[name]) return todo(scope, `new statement is not supported yet`); // return todo(scope, `new statement is not supported yet (new ${unhackName(name)})`);
|
1913
1964
|
|
1914
1965
|
return generateCall(scope, decl, _global, _name);
|
@@ -2174,6 +2225,22 @@ const generateVar = (scope, decl) => {
|
|
2174
2225
|
}
|
2175
2226
|
|
2176
2227
|
if (x.init) {
|
2228
|
+
// if (isFuncType(x.init.type)) {
|
2229
|
+
// // let a = function () { ... }
|
2230
|
+
// x.init.id = { name };
|
2231
|
+
|
2232
|
+
// const func = generateFunc(scope, x.init);
|
2233
|
+
|
2234
|
+
// out.push(
|
2235
|
+
// ...number(func.index - importedFuncs.length),
|
2236
|
+
// [ global ? Opcodes.global_set : Opcodes.local_set, idx ],
|
2237
|
+
|
2238
|
+
// ...setType(scope, name, TYPES.function)
|
2239
|
+
// );
|
2240
|
+
|
2241
|
+
// continue;
|
2242
|
+
// }
|
2243
|
+
|
2177
2244
|
const generated = generate(scope, x.init, global, name);
|
2178
2245
|
if (scope.arrays?.get(name) != null) {
|
2179
2246
|
// hack to set local as pointer before
|
@@ -2185,6 +2252,7 @@ const generateVar = (scope, decl) => {
|
|
2185
2252
|
out = out.concat(generated);
|
2186
2253
|
out.push([ global ? Opcodes.global_set : Opcodes.local_set, idx ]);
|
2187
2254
|
}
|
2255
|
+
|
2188
2256
|
out.push(...setType(scope, name, getNodeType(scope, x.init)));
|
2189
2257
|
}
|
2190
2258
|
|
@@ -2198,6 +2266,7 @@ const generateVar = (scope, decl) => {
|
|
2198
2266
|
// todo: optimize this func for valueUnused
|
2199
2267
|
const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
2200
2268
|
const { type, name } = decl.left;
|
2269
|
+
const [ local, isGlobal ] = lookupName(scope, name);
|
2201
2270
|
|
2202
2271
|
if (type === 'ObjectPattern') {
|
2203
2272
|
// hack: ignore object parts of `var a = {} = 2`
|
@@ -2207,8 +2276,18 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
2207
2276
|
if (isFuncType(decl.right.type)) {
|
2208
2277
|
// hack for a = function () { ... }
|
2209
2278
|
decl.right.id = { name };
|
2210
|
-
|
2211
|
-
|
2279
|
+
|
2280
|
+
const func = generateFunc(scope, decl.right);
|
2281
|
+
|
2282
|
+
return [
|
2283
|
+
...number(func.index - importedFuncs.length),
|
2284
|
+
...(local != null ? [
|
2285
|
+
[ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
|
2286
|
+
[ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ],
|
2287
|
+
|
2288
|
+
...setType(scope, name, TYPES.function)
|
2289
|
+
] : [])
|
2290
|
+
];
|
2212
2291
|
}
|
2213
2292
|
|
2214
2293
|
const op = decl.operator.slice(0, -1) || '=';
|
@@ -2307,8 +2386,6 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
2307
2386
|
|
2308
2387
|
if (!name) return todo(scope, 'destructuring is not supported yet', true);
|
2309
2388
|
|
2310
|
-
const [ local, isGlobal ] = lookupName(scope, name);
|
2311
|
-
|
2312
2389
|
if (local === undefined) {
|
2313
2390
|
// todo: this should be a sloppy mode only thing
|
2314
2391
|
|
@@ -2457,6 +2534,7 @@ const generateUnary = (scope, decl) => {
|
|
2457
2534
|
[TYPES.string]: makeString(scope, 'string', false, '#typeof_result'),
|
2458
2535
|
[TYPES.undefined]: makeString(scope, 'undefined', false, '#typeof_result'),
|
2459
2536
|
[TYPES.function]: makeString(scope, 'function', false, '#typeof_result'),
|
2537
|
+
[TYPES.symbol]: makeString(scope, 'symbol', false, '#typeof_result'),
|
2460
2538
|
|
2461
2539
|
[TYPES.bytestring]: makeString(scope, 'string', false, '#typeof_result'),
|
2462
2540
|
|
@@ -3368,7 +3446,7 @@ const generateFunc = (scope, decl) => {
|
|
3368
3446
|
|
3369
3447
|
if (typedInput && decl.returnType) {
|
3370
3448
|
const { type } = extractTypeAnnotation(decl.returnType);
|
3371
|
-
if (type != null) {
|
3449
|
+
if (type != null && !Prefs.indirectCalls) {
|
3372
3450
|
innerScope.returnType = type;
|
3373
3451
|
innerScope.returns = [ valtypeBinary ];
|
3374
3452
|
}
|
@@ -3586,8 +3664,10 @@ const internalConstrs = {
|
|
3586
3664
|
}),
|
3587
3665
|
|
3588
3666
|
// print space
|
3589
|
-
...
|
3590
|
-
|
3667
|
+
...(i !== decl.arguments.length - 1 ? [
|
3668
|
+
...number(32),
|
3669
|
+
[ Opcodes.call, importedFuncs.printChar ]
|
3670
|
+
] : [])
|
3591
3671
|
);
|
3592
3672
|
}
|
3593
3673
|
|
@@ -3597,6 +3677,8 @@ const internalConstrs = {
|
|
3597
3677
|
[ Opcodes.call, importedFuncs.printChar ]
|
3598
3678
|
);
|
3599
3679
|
|
3680
|
+
out.push(...number(UNDEFINED));
|
3681
|
+
|
3600
3682
|
return out;
|
3601
3683
|
},
|
3602
3684
|
type: TYPES.undefined,
|
@@ -1622,4 +1622,49 @@ export const BuiltinFuncs = function() {
|
|
1622
1622
|
locals: [],
|
1623
1623
|
localNames: ["_this","_this#type"],
|
1624
1624
|
};
|
1625
|
+
this.__Porffor_symbol_descStore = {
|
1626
|
+
wasm: (scope, {allocPage,builtin,}) => [...number(allocPage(scope, 'bytestring: __Porffor_symbol_descStore/ptr', 'i8') * pageSize, 124),[33,4],[32,0],[252,3],[4,64],[32,4],[252,2],[40,0,0],[183],[33,5],[32,4],[252,2],[32,5],[68,0,0,0,0,0,0,240,63],[160],[252,2],[54,0,0],[32,4],[65,18],[32,5],[65,0],[32,2],[32,3],[16, builtin('__Porffor_set_write')],[26],[32,5],[65,0],[15],[5],[32,4],[65,18],[32,2],[32,3],[16, builtin('__Porffor_set_read')],[34,6],[15],[11],[68,0,0,0,0,0,0,0,0],[65,3],[15]],
|
1627
|
+
params: [124,127,124,127],
|
1628
|
+
typedParams: true,
|
1629
|
+
returns: [124,127],
|
1630
|
+
typedReturns: true,
|
1631
|
+
locals: [124,124,127],
|
1632
|
+
localNames: ["op","op#type","value","value#type","ptr","size","#last_type"],
|
1633
|
+
};
|
1634
|
+
this.Symbol = {
|
1635
|
+
wasm: (scope, {builtin,}) => [[68,0,0,0,0,0,0,240,63],[65,1],[32,0],[32,1],[16, builtin('__Porffor_symbol_descStore')],[33,2],[68,0,0,0,0,0,0,240,63],[160],[15]],
|
1636
|
+
params: [124,127],
|
1637
|
+
typedParams: true,
|
1638
|
+
returns: [124],
|
1639
|
+
returnType: 6,
|
1640
|
+
locals: [127],
|
1641
|
+
localNames: ["description","description#type","#last_type"],
|
1642
|
+
};
|
1643
|
+
this.__Symbol_prototype_description = {
|
1644
|
+
wasm: (scope, {builtin,}) => [[68,0,0,0,0,0,0,0,0],[65,1],[32,0],[68,0,0,0,0,0,0,240,63],[161],[65,0],[16, builtin('__Porffor_symbol_descStore')],[33,3],[34,2],[65,18],[15]],
|
1645
|
+
params: [124,127],
|
1646
|
+
typedParams: true,
|
1647
|
+
returns: [124,127],
|
1648
|
+
typedReturns: true,
|
1649
|
+
locals: [124,127],
|
1650
|
+
localNames: ["_this","_this#type","description","#last_type"],
|
1651
|
+
};
|
1652
|
+
this.__Symbol_prototype_toString = {
|
1653
|
+
wasm: (scope, {allocPage,builtin,}) => [...number(allocPage(scope, 'bytestring: __Symbol_prototype_toString/out', 'i8') * pageSize, 124),[34,2],[252,2],[65,211,0],[58,0,4],[32,2],[252,2],[65,249,0],[58,0,5],[32,2],[252,2],[65,237,0],[58,0,6],[32,2],[252,2],[65,226,0],[58,0,7],[32,2],[252,2],[65,239,0],[58,0,8],[32,2],[252,2],[65,236,0],[58,0,9],[32,2],[252,2],[65,40],[58,0,10],[68,0,0,0,0,0,0,0,0],[65,1],[32,0],[68,0,0,0,0,0,0,240,63],[161],[65,0],[16, builtin('__Porffor_symbol_descStore')],[33,4],[34,3],[252,3],[40,1,0],[184],[33,5],[32,2],[68,0,0,0,0,0,0,28,64],[160],[33,6],[32,3],[34,7],[32,5],[160],[33,8],[3,64],[32,7],[32,8],[99],[4,64],[32,6],[32,6],[68,0,0,0,0,0,0,240,63],[160],[33,6],[252,2],[32,7],[32,7],[68,0,0,0,0,0,0,240,63],[160],[33,7],[252,2],[45,0,4],[58,0,4],[12,1],[11],[11],[32,2],[32,5],[160],[252,2],[65,41],[58,0,11],[32,2],[252,3],[68,0,0,0,0,0,0,32,64],[32,5],[160],[34,9],[252,3],[54,1,0],[32,2],[65,18],[15]],
|
1654
|
+
params: [124,127],
|
1655
|
+
typedParams: true,
|
1656
|
+
returns: [124,127],
|
1657
|
+
typedReturns: true,
|
1658
|
+
locals: [124,124,127,124,124,124,124,124],
|
1659
|
+
localNames: ["_this","_this#type","out","description","#last_type","descLen","outPtr","descPtr","descPtrEnd","__length_setter_tmp"],
|
1660
|
+
};
|
1661
|
+
this.__Symbol_prototype_valueOf = {
|
1662
|
+
wasm: (scope, {}) => [[32,0],[65,6],[15]],
|
1663
|
+
params: [124,127],
|
1664
|
+
typedParams: true,
|
1665
|
+
returns: [124,127],
|
1666
|
+
typedReturns: true,
|
1667
|
+
locals: [],
|
1668
|
+
localNames: ["_this","_this#type"],
|
1669
|
+
};
|
1625
1670
|
};
|
package/compiler/index.js
CHANGED
@@ -12,14 +12,7 @@ globalThis.decompile = decompile;
|
|
12
12
|
const logFuncs = (funcs, globals, exceptions) => {
|
13
13
|
console.log('\n' + underline(bold('funcs')));
|
14
14
|
|
15
|
-
const startIndex = funcs.sort((a, b) => a.index - b.index)[0].index;
|
16
15
|
for (const f of funcs) {
|
17
|
-
console.log(`${underline(f.name)} (${f.index - startIndex})`);
|
18
|
-
|
19
|
-
console.log(`params: ${f.params.map((_, i) => Object.keys(f.locals)[Object.values(f.locals).indexOf(Object.values(f.locals).find(x => x.idx === i))]).join(', ')}`);
|
20
|
-
console.log(`returns: ${f.returns.length > 0 ? true : false}`);
|
21
|
-
console.log(`locals: ${Object.keys(f.locals).sort((a, b) => f.locals[a].idx - f.locals[b].idx).map(x => `${x} (${f.locals[x].idx})`).join(', ')}`);
|
22
|
-
console.log();
|
23
16
|
console.log(decompile(f.wasm, f.name, f.index, f.locals, f.params, f.returns, funcs, globals, exceptions));
|
24
17
|
}
|
25
18
|
|
@@ -44,12 +37,14 @@ export default (code, flags) => {
|
|
44
37
|
opt(funcs, globals, pages, tags, exceptions);
|
45
38
|
if (Prefs.profileCompiler) console.log(`3. optimized in ${(performance.now() - t2).toFixed(2)}ms`);
|
46
39
|
|
47
|
-
if (Prefs.optFuncs) logFuncs(funcs, globals, exceptions);
|
40
|
+
// if (Prefs.optFuncs) logFuncs(funcs, globals, exceptions);
|
48
41
|
|
49
42
|
const t3 = performance.now();
|
50
43
|
const wasm = assemble(funcs, globals, tags, pages, data, flags);
|
51
44
|
if (Prefs.profileCompiler) console.log(`4. assembled in ${(performance.now() - t3).toFixed(2)}ms`);
|
52
45
|
|
46
|
+
if (Prefs.optFuncs) logFuncs(funcs, globals, exceptions);
|
47
|
+
|
53
48
|
if (Prefs.allocLog) {
|
54
49
|
const wasmPages = Math.ceil((pages.size * pageSize) / 65536);
|
55
50
|
const bytes = wasmPages * 65536;
|
package/compiler/precompile.js
CHANGED
@@ -18,7 +18,7 @@ const compile = async (file, [ _funcs, _globals ]) => {
|
|
18
18
|
first = source.slice(0, source.indexOf('\n'));
|
19
19
|
}
|
20
20
|
|
21
|
-
let args = ['--bytestring', '--todo-time=compile', '--no-aot-pointer-opt', '--no-treeshake-wasm-imports', '--no-rm-unused-types', '--scoped-page-names', '--funsafe-no-unlikely-proto-checks', '--parse-types', '--opt-types'];
|
21
|
+
let args = ['--bytestring', '--todo-time=compile', '--no-aot-pointer-opt', '--no-indirect-calls', '--no-treeshake-wasm-imports', '--no-rm-unused-types', '--scoped-page-names', '--funsafe-no-unlikely-proto-checks', '--parse-types', '--opt-types'];
|
22
22
|
if (first.startsWith('// @porf')) {
|
23
23
|
args = args.concat(first.slice('// @porf '.length).split(' '));
|
24
24
|
}
|
package/compiler/prefs.js
CHANGED
package/compiler/wrap.js
CHANGED
@@ -1,22 +1,27 @@
|
|
1
|
+
import { encodeVector, encodeLocal } from './encoding.js';
|
2
|
+
import { importedFuncs } from './builtins.js';
|
1
3
|
import compile from './index.js';
|
2
4
|
import decompile from './decompile.js';
|
3
|
-
import { encodeVector, encodeLocal } from './encoding.js';
|
4
5
|
import { TYPES } from './types.js';
|
5
6
|
import { log } from './log.js';
|
6
7
|
import Prefs from './prefs.js';
|
7
8
|
|
8
9
|
const bold = x => `\u001b[1m${x}\u001b[0m`;
|
9
10
|
|
10
|
-
const porfToJSValue = (memory, funcs, value, type) => {
|
11
|
+
const porfToJSValue = ({ memory, funcs, pages }, value, type) => {
|
11
12
|
switch (type) {
|
12
13
|
case TYPES.boolean: return Boolean(value);
|
13
14
|
case TYPES.undefined: return undefined;
|
14
15
|
case TYPES.object: return value === 0 ? null : {};
|
15
16
|
|
16
17
|
case TYPES.function: {
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
let func;
|
19
|
+
if (value < 0) {
|
20
|
+
func = importedFuncs[value + importedFuncs.length];
|
21
|
+
} else {
|
22
|
+
func = funcs.find(x => ((x.originalIndex ?? x.index) - importedFuncs.length) === value);
|
23
|
+
}
|
24
|
+
|
20
25
|
if (!func) return function () {};
|
21
26
|
|
22
27
|
// make fake empty func for repl/etc
|
@@ -61,12 +66,24 @@ const porfToJSValue = (memory, funcs, value, type) => {
|
|
61
66
|
// console.log(' memory:', Array.from(new Uint8Array(memory.buffer, offset, 9)).map(x => x.toString(16).padStart(2, '0')).join(' '));
|
62
67
|
// console.log(' read:', { value: v, type: t }, '\n');
|
63
68
|
|
64
|
-
out.add(porfToJSValue(memory, funcs, v, t));
|
69
|
+
out.add(porfToJSValue({ memory, funcs, pages }, v, t));
|
65
70
|
}
|
66
71
|
|
67
72
|
return out;
|
68
73
|
}
|
69
74
|
|
75
|
+
case TYPES.symbol: {
|
76
|
+
const descStore = pages.get('bytestring: __Porffor_symbol_descStore/ptr').ind * pageSize;
|
77
|
+
const offset = descStore + 4 + ((value - 1) * 9);
|
78
|
+
|
79
|
+
const v = (new Float64Array(memory.buffer.slice(offset, offset + 8), 0, 1))[0];
|
80
|
+
const t = (new Uint8Array(memory.buffer, offset + 8, 1))[0];
|
81
|
+
|
82
|
+
const desc = porfToJSValue({ memory, funcs, pages }, v, t);
|
83
|
+
|
84
|
+
return Symbol(desc);
|
85
|
+
}
|
86
|
+
|
70
87
|
default: return value;
|
71
88
|
}
|
72
89
|
};
|
@@ -213,10 +230,11 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
|
|
213
230
|
exports[func.name] = function() {
|
214
231
|
try {
|
215
232
|
const ret = exp.apply(this, arguments);
|
216
|
-
|
217
233
|
if (ret == null) return undefined;
|
218
234
|
|
219
|
-
|
235
|
+
if (Prefs.rawValue) return { value: ret[0], type: ret[1] };
|
236
|
+
|
237
|
+
return porfToJSValue({ memory, funcs, pages }, ret[0], ret[1]);
|
220
238
|
} catch (e) {
|
221
239
|
if (e.is && e.is(exceptTag)) {
|
222
240
|
const exceptId = e.getArg(exceptTag, 0);
|
package/package.json
CHANGED