porffor 0.41.6 → 0.41.7
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/assemble.js +13 -14
- package/compiler/builtins/_internal_object.ts +3 -60
- package/compiler/builtins.js +8 -10
- package/compiler/builtins_precompiled.js +313 -310
- package/compiler/codegen.js +143 -224
- package/compiler/precompile.js +20 -22
- package/package.json +1 -1
- package/runner/index.js +2 -2
package/compiler/codegen.js
CHANGED
@@ -49,19 +49,81 @@ const cacheAst = (decl, wasm) => {
|
|
49
49
|
};
|
50
50
|
|
51
51
|
const funcRef = func => {
|
52
|
-
// generate func
|
53
52
|
func.generate?.();
|
54
53
|
|
55
54
|
if (globalThis.precompile) return [
|
56
55
|
[ Opcodes.const, 'funcref', func.name ]
|
57
56
|
];
|
58
57
|
|
58
|
+
const wrapperArgc = Prefs.indirectWrapperArgc ?? 6;
|
59
|
+
if (func.returns.length === 2 && countParams(func) < wrapperArgc && !func.wrapperFunc) {
|
60
|
+
const locals = {}, params = [];
|
61
|
+
for (let i = 0; i < wrapperArgc + (func.constr ? 2 : 0); i++) {
|
62
|
+
params.push(valtypeBinary, Valtype.i32);
|
63
|
+
locals[i * 2] = { idx: i * 2, type: valtypeBinary };
|
64
|
+
locals[i * 2 + 1] = { idx: i * 2 + 1, type: Valtype.i32 };
|
65
|
+
}
|
66
|
+
let localInd = (wrapperArgc + (func.constr ? 2 : 0)) * 2;
|
67
|
+
|
68
|
+
const wasm = [];
|
69
|
+
for (let i = 0; i < func.params.length; i++) {
|
70
|
+
wasm.push(
|
71
|
+
[ Opcodes.local_get, i ],
|
72
|
+
...(i % 2 === 0 && func.params[i] === Valtype.i32 ? [ Opcodes.i32_to ]: [])
|
73
|
+
);
|
74
|
+
}
|
75
|
+
|
76
|
+
wasm.push([ Opcodes.call, func.index ]);
|
77
|
+
|
78
|
+
if (func.returns[0] === Valtype.i32) {
|
79
|
+
const localIdx = localInd++;
|
80
|
+
locals[localIdx] = { idx: localIdx, type: Valtype.i32 };
|
81
|
+
|
82
|
+
wasm.push(
|
83
|
+
[ Opcodes.local_set, localIdx ],
|
84
|
+
Opcodes.i32_from,
|
85
|
+
[ Opcodes.local_get, localIdx ]
|
86
|
+
);
|
87
|
+
}
|
88
|
+
|
89
|
+
const name = '#indirect_' + func.name;
|
90
|
+
const wrapperFunc = {
|
91
|
+
name,
|
92
|
+
params,
|
93
|
+
locals, localInd,
|
94
|
+
returns: [ valtypeBinary, Valtype.i32 ],
|
95
|
+
wasm,
|
96
|
+
constr: func.constr,
|
97
|
+
internal: true,
|
98
|
+
index: currentFuncIndex++
|
99
|
+
};
|
100
|
+
|
101
|
+
funcs.push(wrapperFunc);
|
102
|
+
funcIndex[name] = wrapperFunc.index;
|
103
|
+
|
104
|
+
wrapperFunc.jsLength = countLength(func);
|
105
|
+
func.wrapperFunc = wrapperFunc;
|
106
|
+
}
|
107
|
+
|
59
108
|
return [
|
60
109
|
[ Opcodes.const, func.index - importedFuncs.length ]
|
61
|
-
// [ Opcodes.const, func.index - importedFuncs.length, 'funcref' ]
|
62
110
|
];
|
63
111
|
};
|
64
112
|
|
113
|
+
const forceDuoValtype = (scope, wasm, forceValtype) => [
|
114
|
+
...wasm,
|
115
|
+
...(valtypeBinary === Valtype.i32 && forceValtype === Valtype.f64 ? [
|
116
|
+
[ Opcodes.local_set, localTmp(scope, '#swap', Valtype.i32) ],
|
117
|
+
[ Opcodes.f64_convert_i32_s ],
|
118
|
+
[ Opcodes.local_get, localTmp(scope, '#swap', Valtype.i32) ]
|
119
|
+
] : []),
|
120
|
+
...(valtypeBinary === Valtype.f64 && forceValtype === Valtype.i32 ? [
|
121
|
+
[ Opcodes.local_set, localTmp(scope, '#swap', Valtype.i32) ],
|
122
|
+
Opcodes.i32_trunc_sat_f64_s,
|
123
|
+
[ Opcodes.local_get, localTmp(scope, '#swap', Valtype.i32) ]
|
124
|
+
] : [])
|
125
|
+
];
|
126
|
+
|
65
127
|
const generate = (scope, decl, global = false, name = undefined, valueUnused = false) => {
|
66
128
|
if (astCache.has(decl)) return astCache.get(decl);
|
67
129
|
|
@@ -245,7 +307,7 @@ const internalThrow = (scope, constructor, message, expectsValue = Prefs.alwaysV
|
|
245
307
|
]
|
246
308
|
}
|
247
309
|
}),
|
248
|
-
...(expectsValue ? number(UNDEFINED) : [])
|
310
|
+
...(expectsValue ? number(UNDEFINED, typeof expectsValue === 'number' ? expectsValue : valtypeBinary) : [])
|
249
311
|
];
|
250
312
|
|
251
313
|
const generateIdent = (scope, decl) => {
|
@@ -2167,102 +2229,45 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2167
2229
|
} else {
|
2168
2230
|
if (!Prefs.indirectCalls) return internalThrow(scope, 'TypeError', `${unhackName(name)} is not a function`, true);
|
2169
2231
|
|
2170
|
-
// todo: only works when function uses typedParams and typedReturns
|
2171
|
-
|
2172
|
-
const indirectMode = Prefs.indirectCallMode ?? 'vararg';
|
2173
|
-
// options: vararg, strict
|
2174
|
-
// - strict: simpler, smaller size usage, no func lut needed.
|
2175
|
-
// ONLY works when arg count of call == arg count of function being called
|
2176
|
-
// - vararg: large size usage, cursed.
|
2177
|
-
// works when arg count of call != arg count of function being called*
|
2178
|
-
// * most of the time, some edgecases
|
2179
|
-
|
2180
2232
|
funcs.table = true;
|
2181
2233
|
scope.table = true;
|
2182
2234
|
|
2183
2235
|
let args = decl.arguments;
|
2184
|
-
|
2185
|
-
|
2186
|
-
|
2187
|
-
const minArgc = Prefs.indirectCallMinArgc ?? 5;
|
2188
|
-
|
2189
|
-
if (args.length < minArgc) {
|
2190
|
-
args = args.concat(new Array(minArgc - args.length).fill(DEFAULT_VALUE()));
|
2191
|
-
}
|
2236
|
+
const wrapperArgc = Prefs.indirectWrapperArgc ?? 6;
|
2237
|
+
if (args.length < wrapperArgc) {
|
2238
|
+
args = args.concat(new Array(wrapperArgc - args.length).fill(DEFAULT_VALUE()));
|
2192
2239
|
}
|
2193
2240
|
|
2194
2241
|
for (let i = 0; i < args.length; i++) {
|
2195
2242
|
const arg = args[i];
|
2196
|
-
out = out.concat(generate(scope, arg));
|
2197
|
-
out = out.concat(getNodeType(scope, arg));
|
2198
|
-
|
2199
|
-
if (indirectMode === 'vararg') {
|
2200
|
-
const typeLocal = localTmp(scope, `#indirect_arg${i}_type`, Valtype.i32);
|
2201
|
-
const valLocal = localTmp(scope, `#indirect_arg${i}_val`);
|
2202
|
-
|
2203
|
-
locals.push([valLocal, typeLocal]);
|
2204
|
-
|
2205
|
-
out.push(
|
2206
|
-
[ Opcodes.local_set, typeLocal ],
|
2207
|
-
[ Opcodes.local_set, valLocal ]
|
2208
|
-
);
|
2209
|
-
}
|
2243
|
+
out = out.concat(generate(scope, arg), valtypeBinary === Valtype.i32 && scope.locals[arg.name]?.type !== Valtype.f64 ? [ [ Opcodes.f64_convert_i32_s ] ] : [], getNodeType(scope, arg));
|
2210
2244
|
}
|
2211
2245
|
|
2212
|
-
|
2213
|
-
|
2214
|
-
...generate(scope, decl.callee),
|
2215
|
-
[ Opcodes.local_set, localTmp(scope, '#indirect_callee') ],
|
2246
|
+
let knownThis = undefined, getCallee = undefined;
|
2247
|
+
const calleeLocal = localTmp(scope, '#indirect_callee');
|
2216
2248
|
|
2217
|
-
|
2218
|
-
|
2219
|
-
|
2249
|
+
// hack: this should be more thorough, Function.bind, etc
|
2250
|
+
if (decl.callee.type === 'MemberExpression' && !decl._new) {
|
2251
|
+
const thisLocal = localTmp(scope, '#indirect_caller');
|
2252
|
+
const thisLocalType = localTmp(scope, '#indirect_caller#type', Valtype.i32);
|
2220
2253
|
|
2221
|
-
|
2222
|
-
|
2223
|
-
|
2224
|
-
[ Opcodes.call_indirect, args.length, 0 ],
|
2225
|
-
...setLastType(scope)
|
2226
|
-
],
|
2227
|
-
default: internalThrow(scope, 'TypeError', `${unhackName(name)} is not a function`, true)
|
2228
|
-
})
|
2254
|
+
knownThis = [
|
2255
|
+
[ Opcodes.local_get, thisLocal ],
|
2256
|
+
[ Opcodes.local_get, thisLocalType ]
|
2229
2257
|
];
|
2230
|
-
|
2231
|
-
|
2232
|
-
// hi, I will now explain how vararg mode works:
|
2233
|
-
// wasm's indirect_call instruction requires you know the func type at compile-time
|
2234
|
-
// since we have varargs (variable argument count), we do not know it.
|
2235
|
-
// we could just store args in memory and not use wasm func args,
|
2236
|
-
// but that is slow (probably) and breaks js exports.
|
2237
|
-
// instead, we generate every* possibility of argc and use different indirect_call
|
2238
|
-
// ops for each one, with type depending on argc for that branch.
|
2239
|
-
// then we load the argc for the wanted function from a memory lut,
|
2240
|
-
// and call the branch with the matching argc we require.
|
2241
|
-
// sorry, yes it is very cursed (and size inefficient), but indirect calls
|
2242
|
-
// are kind of rare anyway (mostly callbacks) so I am not concerned atm.
|
2243
|
-
// *for argc 0-3, in future (todo:) the max number should be
|
2244
|
-
// dynamically changed to the max argc of any func in the js file.
|
2245
|
-
|
2246
|
-
const funcLocal = localTmp(scope, '#indirect_func', Valtype.i32);
|
2247
|
-
const flags = localTmp(scope, '#indirect_flags', Valtype.i32);
|
2248
|
-
|
2249
|
-
let knownThis = undefined;
|
2250
|
-
let getCalleeObj = undefined;
|
2251
|
-
let initCalleeObj = undefined;
|
2252
|
-
|
2253
|
-
// hack: this should be more thorough, Function.bind, etc
|
2254
|
-
if (decl.callee.type == 'MemberExpression' && !decl._new) {
|
2255
|
-
const callee = localTmp(scope, '#indirect_callee_obj', Valtype.f64);
|
2256
|
-
initCalleeObj = [
|
2258
|
+
getCallee = [
|
2257
2259
|
...generate(scope, decl.callee.object),
|
2258
|
-
[ Opcodes.local_set,
|
2259
|
-
|
2260
|
-
|
2261
|
-
|
2262
|
-
|
2263
|
-
|
2264
|
-
|
2265
|
-
|
2260
|
+
[ Opcodes.local_set, thisLocal ],
|
2261
|
+
...getNodeType(scope, decl.callee.object),
|
2262
|
+
[ Opcodes.local_set, thisLocalType ],
|
2263
|
+
|
2264
|
+
...generate(scope, {
|
2265
|
+
type: 'MemberExpression',
|
2266
|
+
object: { type: 'Identifier', name: '#indirect_caller' },
|
2267
|
+
property: decl.callee.property,
|
2268
|
+
computed: decl.callee.computed,
|
2269
|
+
optional: decl.callee.optional
|
2270
|
+
})
|
2266
2271
|
];
|
2267
2272
|
}
|
2268
2273
|
|
@@ -2278,152 +2283,54 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2278
2283
|
}
|
2279
2284
|
|
2280
2285
|
const newTargetWasm = decl._newTargetWasm ?? createNewTarget(scope, decl, [
|
2281
|
-
[ Opcodes.local_get,
|
2282
|
-
Opcodes.i32_from_u
|
2286
|
+
[ Opcodes.local_get, calleeLocal ]
|
2283
2287
|
], callAsNew);
|
2284
|
-
const thisWasm = knownThis ?? createThisArg(scope, decl);
|
2285
|
-
|
2286
|
-
const gen = argc => {
|
2287
|
-
const argsOut = [];
|
2288
|
-
for (let i = 0; i < argc; i++) {
|
2289
|
-
argsOut.push(
|
2290
|
-
[ Opcodes.local_get, locals[i][0] ],
|
2291
|
-
[ Opcodes.local_get, locals[i][1] ]
|
2292
|
-
);
|
2293
|
-
}
|
2294
|
-
|
2295
|
-
const checkFlag = (flag, pass, fail) => [
|
2296
|
-
[ Opcodes.local_get, flags ],
|
2297
|
-
...number(flag, Valtype.i32),
|
2298
|
-
[ Opcodes.i32_and ],
|
2299
|
-
[ Opcodes.if, valtypeBinary ],
|
2300
|
-
...pass,
|
2301
|
-
[ Opcodes.else ],
|
2302
|
-
...fail,
|
2303
|
-
[ Opcodes.end ]
|
2304
|
-
];
|
2305
|
-
|
2306
|
-
// todo: i'm sure this could be made better somehow, probably only with #96?
|
2307
|
-
return checkFlag(0b1,
|
2308
|
-
// no type return
|
2309
|
-
checkFlag(0b10, [
|
2310
|
-
// no type return & constr
|
2311
|
-
...newTargetWasm,
|
2312
|
-
...thisWasm,
|
2313
|
-
...argsOut,
|
2314
|
-
[ Opcodes.local_get, funcLocal ],
|
2315
|
-
[ Opcodes.call_indirect, argc + 2, 0, 'no_type_return' ],
|
2316
|
-
], [
|
2317
|
-
// no type return & not constr
|
2318
|
-
...argsOut,
|
2319
|
-
[ Opcodes.local_get, funcLocal ],
|
2320
|
-
[ Opcodes.call_indirect, argc, 0, 'no_type_return' ]
|
2321
|
-
]),
|
2322
|
-
|
2323
|
-
// type return
|
2324
|
-
checkFlag(0b10, [
|
2325
|
-
// type return & constr
|
2326
|
-
...newTargetWasm,
|
2327
|
-
...thisWasm,
|
2328
|
-
...argsOut,
|
2329
|
-
[ Opcodes.local_get, funcLocal ],
|
2330
|
-
[ Opcodes.call_indirect, argc + 2, 0 ],
|
2331
|
-
...setLastType(scope),
|
2332
|
-
], [
|
2333
|
-
// type return
|
2334
|
-
...argsOut,
|
2335
|
-
[ Opcodes.local_get, funcLocal ],
|
2336
|
-
[ Opcodes.call_indirect, argc, 0 ],
|
2337
|
-
...setLastType(scope),
|
2338
|
-
])
|
2339
|
-
);
|
2340
|
-
};
|
2341
|
-
|
2342
|
-
const tableBc = {};
|
2343
|
-
for (let i = 0; i <= args.length; i++) {
|
2344
|
-
tableBc[i] = gen(i);
|
2345
|
-
}
|
2346
|
-
|
2347
|
-
// todo/perf: check if we should use br_table here or just generate our own big if..elses
|
2288
|
+
const thisWasm = decl._thisWasm ?? knownThis ?? createThisArg(scope, decl);
|
2348
2289
|
|
2349
2290
|
return [
|
2350
|
-
...(
|
2351
|
-
|
2352
|
-
...generate(scope, callee, false, undefined, getCalleeObj)
|
2353
|
-
]: generate(scope, callee)),
|
2354
|
-
[ Opcodes.local_set, localTmp(scope, '#indirect_callee') ],
|
2291
|
+
...(getCallee ? getCallee : generate(scope, callee)),
|
2292
|
+
[ Opcodes.local_set, calleeLocal ],
|
2355
2293
|
|
2356
2294
|
...typeSwitch(scope, getNodeType(scope, callee), {
|
2357
2295
|
[TYPES.function]: () => [
|
2358
|
-
...out,
|
2359
|
-
|
2360
|
-
[ Opcodes.local_get, localTmp(scope, '#indirect_callee') ],
|
2361
|
-
Opcodes.i32_to_u,
|
2362
|
-
[ Opcodes.local_set, funcLocal ],
|
2363
|
-
|
2364
2296
|
// get if func we are calling is a constructor or not
|
2365
|
-
[ Opcodes.local_get,
|
2366
|
-
|
2297
|
+
[ Opcodes.local_get, calleeLocal ],
|
2298
|
+
Opcodes.i32_to_u,
|
2299
|
+
...number(48, Valtype.i32),
|
2367
2300
|
[ Opcodes.i32_mul ],
|
2368
|
-
...number(
|
2301
|
+
...number(2, Valtype.i32),
|
2369
2302
|
[ Opcodes.i32_add ],
|
2370
2303
|
[ Opcodes.i32_load8_u, 0, ...unsignedLEB128(allocPage(scope, 'func lut')), 'read func lut' ],
|
2371
|
-
[ Opcodes.local_set, flags ],
|
2372
|
-
|
2373
|
-
// check if non-constructor was called with new, if so throw
|
2374
|
-
...(callAsNew ? [
|
2375
|
-
[ Opcodes.local_get, flags ],
|
2376
|
-
...number(0b10, Valtype.i32),
|
2377
|
-
[ Opcodes.i32_and ],
|
2378
|
-
[ Opcodes.i32_eqz ],
|
2379
|
-
[ Opcodes.if, Blocktype.void ],
|
2380
|
-
...internalThrow(scope, 'TypeError', `${unhackName(name)} is not a constructor`),
|
2381
|
-
[ Opcodes.end ],
|
2382
|
-
] : []),
|
2383
|
-
|
2384
|
-
// [ Opcodes.local_get, funcLocal ],
|
2385
|
-
// Opcodes.i32_from_u,
|
2386
|
-
// [ Opcodes.call, 0 ],
|
2387
|
-
|
2388
|
-
// ...number(32),
|
2389
|
-
// [ Opcodes.call, 1 ],
|
2390
|
-
|
2391
|
-
// [ Opcodes.local_get, funcLocal ],
|
2392
|
-
// ...number(64, Valtype.i32),
|
2393
|
-
// [ Opcodes.i32_mul ],
|
2394
|
-
// [ Opcodes.i32_load16_u, 0, ...unsignedLEB128(allocPage(scope, 'func lut')), 'read func lut' ],
|
2395
|
-
// Opcodes.i32_from_u,
|
2396
|
-
// [ Opcodes.call, 0 ],
|
2397
|
-
|
2398
|
-
// [ Opcodes.local_get, funcLocal ],
|
2399
|
-
// [ Opcodes.call, includeBuiltin(scope, '__Porffor_funcLut_name').index ],
|
2400
|
-
// Opcodes.i32_from_u,
|
2401
|
-
// ...number(TYPES.bytestring, Valtype.i32),
|
2402
|
-
// [ Opcodes.call, includeBuiltin(scope, '__Porffor_printString').index ],
|
2403
|
-
// [ Opcodes.drop ],
|
2404
|
-
// [ Opcodes.drop ],
|
2405
|
-
|
2406
|
-
// ...number(10),
|
2407
|
-
// [ Opcodes.call, 1 ],
|
2408
|
-
|
2409
|
-
...brTable([
|
2410
|
-
// get argc of func we are calling
|
2411
|
-
[ Opcodes.local_get, funcLocal ],
|
2412
|
-
...number(64, Valtype.i32),
|
2413
|
-
[ Opcodes.i32_mul ],
|
2414
|
-
[ Opcodes.i32_load16_u, 0, ...unsignedLEB128(allocPage(scope, 'func lut')), 'read func lut' ]
|
2415
|
-
], tableBc, valtypeBinary)
|
2416
|
-
],
|
2417
2304
|
|
2418
|
-
|
2419
|
-
[
|
2420
|
-
|
2421
|
-
...
|
2422
|
-
|
2423
|
-
|
2305
|
+
...number(0b10, Valtype.i32),
|
2306
|
+
[ Opcodes.i32_and ],
|
2307
|
+
[ Opcodes.if, Valtype.f64 ],
|
2308
|
+
...forceDuoValtype(scope, newTargetWasm, Valtype.f64),
|
2309
|
+
...forceDuoValtype(scope, thisWasm, Valtype.f64),
|
2310
|
+
...out,
|
2424
2311
|
|
2425
|
-
|
2426
|
-
|
2312
|
+
[ Opcodes.local_get, calleeLocal ],
|
2313
|
+
Opcodes.i32_to_u,
|
2314
|
+
[ Opcodes.call_indirect, args.length + 2, 0 ],
|
2315
|
+
...setLastType(scope),
|
2316
|
+
[ Opcodes.else ],
|
2317
|
+
// throw if non-constructor called with new
|
2318
|
+
...(callAsNew ? [
|
2319
|
+
...internalThrow(scope, 'TypeError', `${unhackName(name)} is not a constructor`, Valtype.f64)
|
2320
|
+
] : [
|
2321
|
+
...out,
|
2322
|
+
|
2323
|
+
[ Opcodes.local_get, calleeLocal ],
|
2324
|
+
Opcodes.i32_to_u,
|
2325
|
+
[ Opcodes.call_indirect, args.length, 0 ],
|
2326
|
+
...setLastType(scope)
|
2327
|
+
]),
|
2328
|
+
[ Opcodes.end ]
|
2329
|
+
],
|
2330
|
+
|
2331
|
+
default: internalThrow(scope, 'TypeError', `${unhackName(name)} is not a function`, Valtype.f64)
|
2332
|
+
}, Valtype.f64),
|
2333
|
+
...(valtypeBinary === Valtype.i32 && scope.returns[0] !== Valtype.f64 ? [ [ Opcodes.f64_convert_i32_s ] ] : [])
|
2427
2334
|
];
|
2428
2335
|
}
|
2429
2336
|
|
@@ -5288,18 +5195,18 @@ const countLength = (func, name = undefined) => {
|
|
5288
5195
|
|
5289
5196
|
const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) => {
|
5290
5197
|
let final = [], finalEnd, extraBC = {};
|
5291
|
-
|
5198
|
+
let name = decl.object.name;
|
5292
5199
|
|
5293
5200
|
// todo: handle globalThis.foo
|
5294
5201
|
|
5295
5202
|
// hack: .name
|
5296
5203
|
if (decl.property.name === 'name' && hasFuncWithName(name) && !scope.noFastFuncMembers) {
|
5297
|
-
let nameProp = name;
|
5298
|
-
|
5299
5204
|
// eg: __String_prototype_toLowerCase -> toLowerCase
|
5300
|
-
if (
|
5205
|
+
if (name.startsWith('__')) name = name.split('_').pop();
|
5206
|
+
if (name.startsWith('#indirect_')) name = name.slice(10);
|
5207
|
+
if (name.startsWith('#')) name = '';
|
5301
5208
|
|
5302
|
-
return withType(scope, makeString(scope,
|
5209
|
+
return withType(scope, makeString(scope, name, _global, _name, true), TYPES.bytestring);
|
5303
5210
|
}
|
5304
5211
|
|
5305
5212
|
const object = decl.object;
|
@@ -6278,6 +6185,18 @@ const generateFunc = (scope, decl) => {
|
|
6278
6185
|
func.params = Object.values(func.locals).map(x => x.type);
|
6279
6186
|
func.jsLength = jsLength;
|
6280
6187
|
|
6188
|
+
if (globalThis.valtypeOverrides) {
|
6189
|
+
if (globalThis.valtypeOverrides.returns[name]) func.returns = globalThis.valtypeOverrides.returns[name];
|
6190
|
+
if (globalThis.valtypeOverrides.params[name]) {
|
6191
|
+
func.params = globalThis.valtypeOverrides.params[name];
|
6192
|
+
|
6193
|
+
const localsVals = Object.values(func.locals);
|
6194
|
+
for (let i = 0; i < func.params.length; i++) {
|
6195
|
+
localsVals[i].type = func.params[i];
|
6196
|
+
}
|
6197
|
+
}
|
6198
|
+
}
|
6199
|
+
|
6281
6200
|
// force generate for main
|
6282
6201
|
if (name === 'main') func.generate();
|
6283
6202
|
|
package/compiler/precompile.js
CHANGED
@@ -13,6 +13,26 @@ const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
|
13
13
|
globalThis.precompileCompilerPath = __dirname;
|
14
14
|
globalThis.precompile = true;
|
15
15
|
|
16
|
+
globalThis.valtypeOverrides = {
|
17
|
+
returns: {
|
18
|
+
__Porffor_object_get: [ Valtype.f64, Valtype.i32 ],
|
19
|
+
__Porffor_object_getExplicit: [ Valtype.f64, Valtype.i32 ],
|
20
|
+
__Porffor_object_readValue: [ Valtype.f64, Valtype.i32 ],
|
21
|
+
__Porffor_object_set: [ Valtype.f64, Valtype.i32 ],
|
22
|
+
__Porffor_object_setStrict: [ Valtype.f64, Valtype.i32 ],
|
23
|
+
__Porffor_object_packAccessor: [ Valtype.f64, Valtype.i32 ]
|
24
|
+
},
|
25
|
+
params: {
|
26
|
+
__Porffor_object_set: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
|
27
|
+
__Porffor_object_setStrict: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
|
28
|
+
__Porffor_object_expr_init: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
|
29
|
+
__Porffor_object_expr_initWithFlags: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32, Valtype.i32, Valtype.i32 ],
|
30
|
+
__Porffor_object_class_value: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
|
31
|
+
__Porffor_object_class_method: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
|
32
|
+
__Porffor_object_define: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32, Valtype.i32, Valtype.i32 ],
|
33
|
+
}
|
34
|
+
};
|
35
|
+
|
16
36
|
const argv = process.argv.slice();
|
17
37
|
|
18
38
|
const timing = {};
|
@@ -50,25 +70,6 @@ const compile = async (file, _funcs) => {
|
|
50
70
|
return acc;
|
51
71
|
}, {});
|
52
72
|
|
53
|
-
const returnOverrides = {
|
54
|
-
__Porffor_object_get: [ Valtype.f64, Valtype.i32 ],
|
55
|
-
__Porffor_object_getExplicit: [ Valtype.f64, Valtype.i32 ],
|
56
|
-
__Porffor_object_readValue: [ Valtype.f64, Valtype.i32 ],
|
57
|
-
__Porffor_object_set: [ Valtype.f64, Valtype.i32 ],
|
58
|
-
__Porffor_object_setStrict: [ Valtype.f64, Valtype.i32 ],
|
59
|
-
__Porffor_object_packAccessor: [ Valtype.f64, Valtype.i32 ]
|
60
|
-
};
|
61
|
-
|
62
|
-
const paramOverrides = {
|
63
|
-
__Porffor_object_set: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
|
64
|
-
__Porffor_object_setStrict: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
|
65
|
-
__Porffor_object_expr_init: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
|
66
|
-
__Porffor_object_expr_initWithFlags: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32, Valtype.i32, Valtype.i32 ],
|
67
|
-
__Porffor_object_class_value: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
|
68
|
-
__Porffor_object_class_method: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32 ],
|
69
|
-
__Porffor_object_define: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.f64, Valtype.i32, Valtype.i32, Valtype.i32 ],
|
70
|
-
};
|
71
|
-
|
72
73
|
const main = funcs.find(x => x.name === 'main');
|
73
74
|
const exports = funcs.filter(x => x.export && x.name !== 'main');
|
74
75
|
for (const x of exports) {
|
@@ -84,9 +85,6 @@ const compile = async (file, _funcs) => {
|
|
84
85
|
}).filter(x => x);
|
85
86
|
}
|
86
87
|
|
87
|
-
if (returnOverrides[x.name]) x.returns = returnOverrides[x.name];
|
88
|
-
if (paramOverrides[x.name]) x.params = paramOverrides[x.name];
|
89
|
-
|
90
88
|
const rewriteWasm = (x, wasm, rewriteLocals = false) => {
|
91
89
|
const locals = Object.keys(x.locals).reduce((acc, y) => {
|
92
90
|
acc[x.locals[y].idx] = { ...x.locals[y], name: y };
|
package/package.json
CHANGED
package/runner/index.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
import fs from 'node:fs';
|
3
|
-
globalThis.version = '0.41.
|
3
|
+
globalThis.version = '0.41.7+89be416c1';
|
4
4
|
|
5
5
|
// deno compat
|
6
6
|
if (typeof process === 'undefined' && typeof Deno !== 'undefined') {
|
@@ -167,7 +167,7 @@ try {
|
|
167
167
|
}
|
168
168
|
} catch (e) {
|
169
169
|
let out = e;
|
170
|
-
if (!process.argv.includes('-d') && Object.getPrototypeOf(e).message != null) out = `${e.
|
170
|
+
if (!process.argv.includes('-d') && Object.getPrototypeOf(e).message != null) out = `${e.name}${e.message != null ? `: ${e.message}` : ''}`;
|
171
171
|
console.error(out);
|
172
172
|
}
|
173
173
|
|