| 28 | } |
| 29 | |
| 30 | void ParseContext::post_process() { |
| 31 | std::unordered_map<index_t, index_t> typemap; |
| 32 | { |
| 33 | // Deduplicate types |
| 34 | std::unordered_map<FuncType, index_t> funcmap; |
| 35 | std::vector<FuncType> functypes; |
| 36 | for (index_t i = 0; i < module_.types.size(); ++i) { |
| 37 | if (funcmap.contains(module_.types[i])) { |
| 38 | typemap[i] = funcmap[module_.types[i]]; |
| 39 | } else { |
| 40 | funcmap[module_.types[i]] = functypes.size(); |
| 41 | typemap[i] = functypes.size(); |
| 42 | functypes.emplace_back(module_.types[i]); |
| 43 | } |
| 44 | } |
| 45 | module_.types = functypes; |
| 46 | } |
| 47 | std::unordered_map<index_t, index_t> funcmap = reorder_map(func_map_); |
| 48 | std::unordered_map<index_t, index_t> tablemap = reorder_map(table_map_); |
| 49 | std::unordered_map<index_t, index_t> memorymap = reorder_map(mem_map_); |
| 50 | std::unordered_map<index_t, index_t> globalmap = reorder_map(global_map_); |
| 51 | |
| 52 | // funcs |
| 53 | for (WasmFunc& func : module_.funcs) { |
| 54 | if (typemap.contains(func.typeidx)) |
| 55 | func.typeidx = typemap[func.typeidx]; |
| 56 | for (WasmInstr& instr : func.body) { |
| 57 | switch(instr.opcode) { |
| 58 | case Opcode::Block: case Opcode::Loop: case Opcode::If: { |
| 59 | auto& blk = std::get<WasmInstr::BlockType>(instr.imm); |
| 60 | if (blk.type && typemap.contains(blk.type.value())) blk.type = typemap[blk.type.value()]; |
| 61 | } break; |
| 62 | case Opcode::Call_indirect: { |
| 63 | auto& tw = std::get<WasmInstr::TwoIdx>(instr.imm); |
| 64 | if (typemap.contains(tw.b)) tw.b = typemap[tw.b]; // b = typeidx |
| 65 | } break; |
| 66 | case Opcode::Ref_func: { |
| 67 | auto& o = std::get<WasmInstr::OneIdx>(instr.imm); |
| 68 | if (funcmap.contains(o.index)) o.index = funcmap[o.index]; |
| 69 | } break; |
| 70 | case Opcode::Global_get: case Opcode::Global_set: { |
| 71 | auto& o = std::get<WasmInstr::OneIdx>(instr.imm); |
| 72 | if (globalmap.contains(o.index)) o.index = globalmap[o.index]; |
| 73 | } break; |
| 74 | case Opcode::Table_get: case Opcode::Table_set: |
| 75 | case Opcode::Table_size: case Opcode::Table_grow: case Opcode::Table_fill: { |
| 76 | auto& o = std::get<WasmInstr::OneIdx>(instr.imm); |
| 77 | if (tablemap.contains(o.index)) o.index = tablemap[o.index]; |
| 78 | } break; |
| 79 | case Opcode::Table_copy: { |
| 80 | auto& tw = std::get<WasmInstr::TwoIdx>(instr.imm); |
| 81 | if (tablemap.contains(tw.a)) tw.a = tablemap[tw.a]; // a = dstidx |
| 82 | if (tablemap.contains(tw.b)) tw.b = tablemap[tw.b]; // b = srcidx |
| 83 | } break; |
| 84 | case Opcode::Table_init: { |
| 85 | auto& tw = std::get<WasmInstr::TwoIdx>(instr.imm); |
| 86 | if (tablemap.contains(tw.a)) tw.a = tablemap[tw.a]; // a = tableidx |
| 87 | } break; |
nothing calls this directly
no outgoing calls
no test coverage detected