Implement function type de-duplication

This commit is contained in:
2026-03-14 19:10:03 +00:00
parent 1105daaad0
commit 580d5d2a4a

50
asm.js
View File

@@ -708,6 +708,7 @@ export class Assembler {
this.data = []; this.data = [];
this.defs = {}; this.defs = {};
this.blocks = []; this.blocks = [];
this.types = [];
} }
action_append(action) { action_append(action) {
@@ -899,19 +900,8 @@ export class Assembler {
} }
wasm_section_type() { wasm_section_type() {
const funcs = Object.values(this.funcs); if (this.types.length == 0) return null;
if (funcs.length == 0) return null; return [ this.types.length ].concat(...this.types);
const contents = funcs.map(({ params, results }) => {
const param_types = Object.values(params);
return [
types["func"],
param_types.length,
...param_types,
results.length,
...results,
];
});
return [ contents.length ].concat(...contents);
} }
wasm_section_import() { wasm_section_import() {
@@ -933,9 +923,10 @@ export class Assembler {
} }
wasm_section_func() { wasm_section_func() {
const func_count = Object.entries(this.funcs).length; const types = Object.values(this.funcs).map(({type}) => type);
if (func_count == 0) return null; const count = types.length;
return [ func_count, ...Array(func_count).keys() ]; if (count == 0) return null;
return [ count, ...types ];
} }
wasm_section_mem() { wasm_section_mem() {
@@ -1014,6 +1005,8 @@ export class Assembler {
} }
wasm() { wasm() {
this.resolve_func_types();
const template = [ const template = [
[ Section.TYPE, () => this.wasm_section_type() ], [ Section.TYPE, () => this.wasm_section_type() ],
[ Section.IMPORT, () => this.wasm_section_import() ], [ Section.IMPORT, () => this.wasm_section_import() ],
@@ -1038,4 +1031,29 @@ export class Assembler {
else else
return [ flags, init ]; return [ flags, init ];
} }
func_type({ params, results }) {
const param_types = Object.values(params);
return [
types["func"],
param_types.length,
...param_types,
results.length,
...results,
];
}
array_eq(a, b) {
return a.length == b.length && a.every((x, i) => x == b[i]);
}
ensure_type(type) {
const index = this.types.findIndex((t) => this.array_eq(type, t));
return index != -1 ? index : this.types.push(type) - 1;
}
resolve_func_types() {
for (const func of Object.values(this.funcs))
func.type = this.ensure_type(this.func_type(func));
}
} }