porffor 0.37.6 → 0.37.8
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/allocators.js +0 -5
- package/compiler/builtins_precompiled.js +1289 -702
- package/compiler/codegen.js +206 -154
- package/compiler/opt.js +0 -113
- package/compiler/precompile.js +11 -6
- package/package.json +1 -1
- package/runner/index.js +1 -1
package/compiler/opt.js
CHANGED
@@ -4,40 +4,6 @@ import { read_signedLEB128, read_ieee754_binary64 } from './encoding.js';
|
|
4
4
|
import { log } from './log.js';
|
5
5
|
import {} from './prefs.js';
|
6
6
|
|
7
|
-
const forceRemoveTypes = new Set(Prefs.forceRemoveTypes?.split?.(','));
|
8
|
-
const hasType = (funcs, pages, type) => {
|
9
|
-
if (forceRemoveTypes.has(type)) return false;
|
10
|
-
|
11
|
-
switch (type) {
|
12
|
-
case 'Array':
|
13
|
-
return pages.hasArray;
|
14
|
-
case 'String':
|
15
|
-
return pages.hasString;
|
16
|
-
case 'ByteString':
|
17
|
-
return pages.hasByteString;
|
18
|
-
|
19
|
-
case 'Map':
|
20
|
-
case 'Set':
|
21
|
-
case 'WeakMap':
|
22
|
-
case 'WeakSet':
|
23
|
-
case 'WeakRef':
|
24
|
-
case 'Date':
|
25
|
-
case 'Uint8Array':
|
26
|
-
case 'Int8Array':
|
27
|
-
case 'Uint8ClampedArray':
|
28
|
-
case 'Uint16Array':
|
29
|
-
case 'Int16Array':
|
30
|
-
case 'Uint32Array':
|
31
|
-
case 'Int32Array':
|
32
|
-
case 'Float32Array':
|
33
|
-
case 'Float64Array':
|
34
|
-
return funcs.some(x => x.name === type);
|
35
|
-
|
36
|
-
default:
|
37
|
-
return true;
|
38
|
-
}
|
39
|
-
}
|
40
|
-
|
41
7
|
export default (funcs, globals, pages, tags, exceptions) => {
|
42
8
|
const optLevel = parseInt(process.argv.find(x => x.startsWith('-O'))?.[2] ?? 1);
|
43
9
|
if (optLevel === 0) return;
|
@@ -189,85 +155,6 @@ export default (funcs, globals, pages, tags, exceptions) => {
|
|
189
155
|
}
|
190
156
|
}
|
191
157
|
|
192
|
-
if (inst[inst.length - 1] === 'string_only' && !pages.hasAnyString && Prefs.rmUnusedTypes) {
|
193
|
-
// remove this inst
|
194
|
-
wasm.splice(i, 1);
|
195
|
-
if (i > 0) i--;
|
196
|
-
inst = wasm[i];
|
197
|
-
}
|
198
|
-
|
199
|
-
if (inst[inst.length - 1] === 'string_only|start' && !pages.hasAnyString && Prefs.rmUnusedTypes) {
|
200
|
-
let j = i;
|
201
|
-
for (; j < wasm.length; j++) {
|
202
|
-
const op = wasm[j];
|
203
|
-
if (op[op.length - 1] === 'string_only|end') break;
|
204
|
-
}
|
205
|
-
|
206
|
-
// remove section
|
207
|
-
wasm.splice(i, 1 + j - i);
|
208
|
-
|
209
|
-
if (i > 0) i--;
|
210
|
-
inst = wasm[i];
|
211
|
-
}
|
212
|
-
|
213
|
-
if (inst[0] === Opcodes.if && typeof inst[2] === 'string' && Prefs.rmUnusedTypes) {
|
214
|
-
// remove unneeded typeswitch checks
|
215
|
-
|
216
|
-
const types = inst[2].split('|')[1].split(',');
|
217
|
-
let missing = true;
|
218
|
-
for (const type of types) {
|
219
|
-
if (hasType(funcs, pages, type)) {
|
220
|
-
missing = false;
|
221
|
-
break;
|
222
|
-
}
|
223
|
-
}
|
224
|
-
|
225
|
-
if (missing) {
|
226
|
-
let j = i, depth = 0;
|
227
|
-
for (; j < wasm.length; j++) {
|
228
|
-
const op = wasm[j][0];
|
229
|
-
if (op === Opcodes.if || op === Opcodes.block || op === Opcodes.loop || op === Opcodes.try) depth++;
|
230
|
-
if (op === Opcodes.end) {
|
231
|
-
depth--;
|
232
|
-
if (depth <= 0) break;
|
233
|
-
}
|
234
|
-
}
|
235
|
-
|
236
|
-
const offset = 3 + 4 * (types.length - 1);
|
237
|
-
wasm.splice(i - offset, j - (i - offset) + 1); // remove cond and this if
|
238
|
-
i -= 1 + offset;
|
239
|
-
inst = wasm[i];
|
240
|
-
|
241
|
-
if (Prefs.optLog) log('opt', `removed unneeded typeswitch check (${types})`);
|
242
|
-
}
|
243
|
-
}
|
244
|
-
|
245
|
-
if (inst[0] === Opcodes.end && inst[1] === 'TYPESWITCH_end' && Prefs.rmUnusedTypes) {
|
246
|
-
// remove unneeded entire typeswitch
|
247
|
-
|
248
|
-
let j = i - 1, depth = -1, checks = 0;
|
249
|
-
for (; j > 0; j--) {
|
250
|
-
const op = wasm[j][0];
|
251
|
-
if (op === Opcodes.if || op === Opcodes.block || op === Opcodes.loop || op === Opcodes.try) {
|
252
|
-
depth++;
|
253
|
-
if (depth === 0) break;
|
254
|
-
}
|
255
|
-
if (op === Opcodes.end) depth--;
|
256
|
-
if (wasm[j][2]?.startsWith?.('TYPESWITCH')) checks++;
|
257
|
-
}
|
258
|
-
|
259
|
-
if (checks === 0) {
|
260
|
-
// todo: review indexes below
|
261
|
-
wasm.splice(j - 1, 2, [ Opcodes.drop ]); // remove typeswitch start
|
262
|
-
wasm.splice(i - 1, 1); // remove this inst
|
263
|
-
|
264
|
-
if (Prefs.optLog) log('opt', 'removed unneeded entire typeswitch');
|
265
|
-
|
266
|
-
if (i > 0) i--;
|
267
|
-
continue;
|
268
|
-
}
|
269
|
-
}
|
270
|
-
|
271
158
|
// remove setting last type if it is never gotten
|
272
159
|
if (!f.internal && !f.gotLastType && inst[0] === Opcodes.local_set && inst[1] === lastType) {
|
273
160
|
// replace this inst with drop
|
package/compiler/precompile.js
CHANGED
@@ -204,19 +204,21 @@ import { number } from './embedding.js';
|
|
204
204
|
export const BuiltinFuncs = function() {
|
205
205
|
${funcs.map(x => {
|
206
206
|
const rewriteWasm = wasm => {
|
207
|
-
const str = JSON.stringify(wasm.filter(x => x.length && x[0] != null), (k, v) => {
|
208
|
-
|
209
|
-
|
210
|
-
|
207
|
+
const str = JSON.stringify(wasm.filter(x => x.length && (x[0] != null || typeof x[1] === 'string')), (k, v) => {
|
208
|
+
if (Number.isNaN(v) || v === Infinity || v === -Infinity) return v.toString();
|
209
|
+
return v;
|
210
|
+
})
|
211
211
|
.replace(/\["alloc","(.*?)","(.*?)",(.*?)\]/g, (_, reason, type, valtype) => `...number(allocPage(_,'${reason}','${type}'),${valtype})`)
|
212
212
|
.replace(/\["global",(.*?),"(.*?)",(.*?)\]/g, (_, opcode, name, valtype) => `...glbl(${opcode},'${name}',${valtype})`)
|
213
213
|
.replace(/\"local","(.*?)",(.*?)\]/g, (_, name, valtype) => `loc('${name}',${valtype})]`)
|
214
214
|
.replace(/\[16,"(.*?)"]/g, (_, name) => `[16,builtin('${name}')]`)
|
215
215
|
.replace(/\[68,"funcref","(.*?)"]/g, (_, name) => `...funcRef('${name}')`)
|
216
216
|
.replace(/\["throw","(.*?)","(.*?)"\]/g, (_, constructor, message) => `...internalThrow(_,'${constructor}',\`${message}\`)`)
|
217
|
-
.replace(/\["get object","(.*?)"\]/g, (_, objName) => `...generateIdent(_,{name:'${objName}'})`)
|
217
|
+
.replace(/\["get object","(.*?)"\]/g, (_, objName) => `...generateIdent(_,{name:'${objName}'})`)
|
218
|
+
.replace(/\[null,"typeswitch case start",\[(.*?)\]\],/g, (_, types) => `...t([${types}],()=>[`)
|
219
|
+
.replaceAll(',[null,"typeswitch case end"]', '])');
|
218
220
|
|
219
|
-
return `(_,{${`${str.includes('allocPage(') ? 'allocPage,' : ''}${str.includes('glbl(') ? 'glbl,' : ''}${str.includes('loc(') ? 'loc,' : ''}${str.includes('builtin(') ? 'builtin,' : ''}${str.includes('funcRef(') ? 'funcRef,' : ''}${str.includes('internalThrow(') ? 'internalThrow,' : ''}${str.includes('generateIdent(') ? 'generateIdent,' : ''}`.slice(0, -1)}})=>`.replace('_,{}', '') + str;
|
221
|
+
return `(_,{${str.includes('...t(') ? 't,' : ''}${`${str.includes('allocPage(') ? 'allocPage,' : ''}${str.includes('glbl(') ? 'glbl,' : ''}${str.includes('loc(') ? 'loc,' : ''}${str.includes('builtin(') ? 'builtin,' : ''}${str.includes('funcRef(') ? 'funcRef,' : ''}${str.includes('internalThrow(') ? 'internalThrow,' : ''}${str.includes('generateIdent(') ? 'generateIdent,' : ''}`.slice(0, -1)}})=>`.replace('_,{}', '') + str;
|
220
222
|
};
|
221
223
|
|
222
224
|
const locals = Object.entries(x.locals).sort((a,b) => a[1].idx - b[1].idx)
|
@@ -224,10 +226,13 @@ ${funcs.map(x => {
|
|
224
226
|
// todo: check for other identifier unsafe characters
|
225
227
|
const name = x.name.includes('#') ? `['${x.name}']` : `.${x.name}`;
|
226
228
|
|
229
|
+
const usedTypes = [...(x.usedTypes ?? [])].filter(x => ![ TYPES.empty, TYPES.undefined, TYPES.number, TYPES.boolean, TYPES.function ].includes(x));
|
230
|
+
|
227
231
|
return `this${name} = {
|
228
232
|
wasm:${rewriteWasm(x.wasm)},
|
229
233
|
params:${JSON.stringify(x.params)},typedParams:1,returns:${JSON.stringify(x.returns)},${x.returnType != null ? `returnType:${JSON.stringify(x.returnType)}` : 'typedReturns:1'},
|
230
234
|
locals:${JSON.stringify(locals.slice(x.params.length).map(x => x[1].type))},localNames:${JSON.stringify(locals.map(x => x[0]))},
|
235
|
+
${usedTypes.length > 0 ? `usedTypes:${JSON.stringify(usedTypes)},` : ''}
|
231
236
|
${x.globalInits ? `globalInits:{${Object.keys(x.globalInits).map(y => `${y}:${rewriteWasm(x.globalInits[y])}`).join(',')}},` : ''}${x.data && Object.keys(x.data).length > 0 ? `data:${JSON.stringify(x.data)},` : ''}
|
232
237
|
${x.table ? `table:1,` : ''}${x.constr ? `constr:1,` : ''}${x.hasRestArgument ? `hasRestArgument:1,` : ''}
|
233
238
|
};`.replaceAll('\n\n', '\n').replaceAll('\n\n', '\n').replaceAll('\n\n', '\n');
|
package/package.json
CHANGED