porffor 0.14.0-7bef6473d → 0.14.0-f67c123a1
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/codegen.js +58 -16
- package/compiler/wrap.js +10 -5
- package/package.json +1 -1
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('__')) {
|
@@ -1831,7 +1832,23 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1831
1832
|
}
|
1832
1833
|
|
1833
1834
|
if (idx === undefined) {
|
1834
|
-
if (scope.locals[name] !== undefined || globals[name] !== undefined || builtinVars[name] !== undefined)
|
1835
|
+
if (scope.locals[name] !== undefined || globals[name] !== undefined || builtinVars[name] !== undefined) {
|
1836
|
+
if (!Prefs.indirectCalls) return internalThrow(scope, 'TypeError', `${unhackName(name)} is not a function`, true);
|
1837
|
+
|
1838
|
+
const [ local, global ] = lookupName(scope, name);
|
1839
|
+
funcs.table = true;
|
1840
|
+
|
1841
|
+
// todo: only works when:
|
1842
|
+
// 1. arg count matches arg count of function
|
1843
|
+
// 2. function uses typedParams and typedReturns
|
1844
|
+
return typeSwitch(scope, getNodeType(decl.callee), {
|
1845
|
+
[TYPES.function]: [
|
1846
|
+
[ global ? Opcodes.global_get : Opcodes.local_get, local.idx ],
|
1847
|
+
[ Opcodes.call_indirect ]
|
1848
|
+
],
|
1849
|
+
default: internalThrow(scope, 'TypeError', `${unhackName(name)} is not a function`, true)
|
1850
|
+
});
|
1851
|
+
}
|
1835
1852
|
return internalThrow(scope, 'ReferenceError', `${unhackName(name)} is not defined`, true);
|
1836
1853
|
}
|
1837
1854
|
|
@@ -1860,11 +1877,10 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1860
1877
|
const arg = args[i];
|
1861
1878
|
out = out.concat(generate(scope, arg));
|
1862
1879
|
|
1863
|
-
if (
|
1864
|
-
|
1865
|
-
|
1866
|
-
|
1867
|
-
if (importedFuncs[name] && name.startsWith('profile')) {
|
1880
|
+
if (valtypeBinary !== Valtype.i32 && (
|
1881
|
+
(builtinFuncs[name] && builtinFuncs[name].params[i * (typedParams ? 2 : 1)] === Valtype.i32) ||
|
1882
|
+
(importedFuncs[name] && name.startsWith('profile'))
|
1883
|
+
)) {
|
1868
1884
|
out.push(Opcodes.i32_to);
|
1869
1885
|
}
|
1870
1886
|
|
@@ -2174,6 +2190,22 @@ const generateVar = (scope, decl) => {
|
|
2174
2190
|
}
|
2175
2191
|
|
2176
2192
|
if (x.init) {
|
2193
|
+
// if (isFuncType(x.init.type)) {
|
2194
|
+
// // let a = function () { ... }
|
2195
|
+
// x.init.id = { name };
|
2196
|
+
|
2197
|
+
// const func = generateFunc(scope, x.init);
|
2198
|
+
|
2199
|
+
// out.push(
|
2200
|
+
// ...number(func.index - importedFuncs.length),
|
2201
|
+
// [ global ? Opcodes.global_set : Opcodes.local_set, idx ],
|
2202
|
+
|
2203
|
+
// ...setType(scope, name, TYPES.function)
|
2204
|
+
// );
|
2205
|
+
|
2206
|
+
// continue;
|
2207
|
+
// }
|
2208
|
+
|
2177
2209
|
const generated = generate(scope, x.init, global, name);
|
2178
2210
|
if (scope.arrays?.get(name) != null) {
|
2179
2211
|
// hack to set local as pointer before
|
@@ -2185,6 +2217,7 @@ const generateVar = (scope, decl) => {
|
|
2185
2217
|
out = out.concat(generated);
|
2186
2218
|
out.push([ global ? Opcodes.global_set : Opcodes.local_set, idx ]);
|
2187
2219
|
}
|
2220
|
+
|
2188
2221
|
out.push(...setType(scope, name, getNodeType(scope, x.init)));
|
2189
2222
|
}
|
2190
2223
|
|
@@ -2198,6 +2231,7 @@ const generateVar = (scope, decl) => {
|
|
2198
2231
|
// todo: optimize this func for valueUnused
|
2199
2232
|
const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
2200
2233
|
const { type, name } = decl.left;
|
2234
|
+
const [ local, isGlobal ] = lookupName(scope, name);
|
2201
2235
|
|
2202
2236
|
if (type === 'ObjectPattern') {
|
2203
2237
|
// hack: ignore object parts of `var a = {} = 2`
|
@@ -2207,8 +2241,18 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
2207
2241
|
if (isFuncType(decl.right.type)) {
|
2208
2242
|
// hack for a = function () { ... }
|
2209
2243
|
decl.right.id = { name };
|
2210
|
-
|
2211
|
-
|
2244
|
+
|
2245
|
+
const func = generateFunc(scope, decl.right);
|
2246
|
+
|
2247
|
+
return [
|
2248
|
+
...number(func.index - importedFuncs.length),
|
2249
|
+
...(local != null ? [
|
2250
|
+
[ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
|
2251
|
+
[ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ],
|
2252
|
+
|
2253
|
+
...setType(scope, name, TYPES.function)
|
2254
|
+
] : [])
|
2255
|
+
];
|
2212
2256
|
}
|
2213
2257
|
|
2214
2258
|
const op = decl.operator.slice(0, -1) || '=';
|
@@ -2307,8 +2351,6 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
2307
2351
|
|
2308
2352
|
if (!name) return todo(scope, 'destructuring is not supported yet', true);
|
2309
2353
|
|
2310
|
-
const [ local, isGlobal ] = lookupName(scope, name);
|
2311
|
-
|
2312
2354
|
if (local === undefined) {
|
2313
2355
|
// todo: this should be a sloppy mode only thing
|
2314
2356
|
|
@@ -3368,7 +3410,7 @@ const generateFunc = (scope, decl) => {
|
|
3368
3410
|
|
3369
3411
|
if (typedInput && decl.returnType) {
|
3370
3412
|
const { type } = extractTypeAnnotation(decl.returnType);
|
3371
|
-
if (type != null) {
|
3413
|
+
if (type != null && !Prefs.indirectCalls) {
|
3372
3414
|
innerScope.returnType = type;
|
3373
3415
|
innerScope.returns = [ valtypeBinary ];
|
3374
3416
|
}
|
package/compiler/wrap.js
CHANGED
@@ -1,6 +1,7 @@
|
|
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';
|
@@ -14,9 +15,13 @@ const porfToJSValue = (memory, funcs, value, type) => {
|
|
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
|
@@ -216,7 +221,7 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
|
|
216
221
|
|
217
222
|
if (ret == null) return undefined;
|
218
223
|
|
219
|
-
return porfToJSValue(memory, funcs, ret[0], ret[1])
|
224
|
+
return porfToJSValue(memory, funcs, ret[0], ret[1]);
|
220
225
|
} catch (e) {
|
221
226
|
if (e.is && e.is(exceptTag)) {
|
222
227
|
const exceptId = e.getArg(exceptTag, 0);
|
package/package.json
CHANGED