diff --git a/asm.js b/asm.js index 5099352..d10eedb 100644 --- a/asm.js +++ b/asm.js @@ -708,6 +708,7 @@ export class Assembler { this.data = []; this.defs = {}; this.blocks = []; + this.types = []; } action_append(action) { @@ -899,19 +900,8 @@ export class Assembler { } wasm_section_type() { - const funcs = Object.values(this.funcs); - if (funcs.length == 0) return null; - 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); + if (this.types.length == 0) return null; + return [ this.types.length ].concat(...this.types); } wasm_section_import() { @@ -933,9 +923,10 @@ export class Assembler { } wasm_section_func() { - const func_count = Object.entries(this.funcs).length; - if (func_count == 0) return null; - return [ func_count, ...Array(func_count).keys() ]; + const types = Object.values(this.funcs).map(({type}) => type); + const count = types.length; + if (count == 0) return null; + return [ count, ...types ]; } wasm_section_mem() { @@ -1014,6 +1005,8 @@ export class Assembler { } wasm() { + this.resolve_func_types(); + const template = [ [ Section.TYPE, () => this.wasm_section_type() ], [ Section.IMPORT, () => this.wasm_section_import() ], @@ -1038,4 +1031,29 @@ export class Assembler { else 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)); + } }