| 192 | } |
| 193 | |
| 194 | WasmModule Linker::get(){ |
| 195 | /** Resolve pending imports **/ |
| 196 | // Create export map |
| 197 | std::unordered_map<std::string, std::unordered_map<std::string, ExternEntry>> export_map; |
| 198 | for(index_t module_idx = 0; module_idx < modules.size(); ++module_idx){ |
| 199 | ModuleEntry& moduleEntry = modules[module_idx]; |
| 200 | for(auto export_ : moduleEntry.exports){ |
| 201 | export_map[moduleEntry.path.string()][export_.name] = ExternEntry {module_idx, export_.index}; |
| 202 | } |
| 203 | } |
| 204 | // Resolve imports |
| 205 | for(ModuleEntry& module_entry : modules){ |
| 206 | resolve_imports(export_map, module_entry.funcs); |
| 207 | resolve_imports(export_map, module_entry.tables); |
| 208 | resolve_imports(export_map, module_entry.mems); |
| 209 | resolve_imports(export_map, module_entry.globals); |
| 210 | } |
| 211 | // Trace exports |
| 212 | for(index_t module_idx = 0; module_idx < modules.size(); ++module_idx){ |
| 213 | trace_extern_entries(funcs) |
| 214 | trace_extern_entries(tables) |
| 215 | trace_extern_entries(mems) |
| 216 | trace_extern_entries(globals) |
| 217 | } |
| 218 | |
| 219 | /** Update indices **/ |
| 220 | // Funcs |
| 221 | for(index_t func_idx = 0; func_idx < output.funcs.size(); ++func_idx){ |
| 222 | WasmFunc& func = output.funcs[func_idx]; |
| 223 | for(WasmInstr& instr : func.body){ |
| 224 | instr_update_indices(instr, modules[module_index_list.funcs[func_idx]]); |
| 225 | } |
| 226 | } |
| 227 | // Globals |
| 228 | for(index_t global_idx = 0; global_idx < output.globals.size(); ++global_idx){ |
| 229 | WasmGlobal& global = output.globals[global_idx]; |
| 230 | instr_update_indices(global.init, modules[module_index_list.globals[global_idx]]); |
| 231 | } |
| 232 | // Elems |
| 233 | for(index_t elem_idx = 0; elem_idx < output.elems.size(); ++elem_idx){ |
| 234 | WasmElem& elem = output.elems[elem_idx]; |
| 235 | ModuleEntry& module_entry = modules[module_index_list.elems[elem_idx]]; |
| 236 | for(ConstInstr& instr : elem.elemlist){ |
| 237 | instr_update_indices(instr, module_entry); |
| 238 | } |
| 239 | IndexEntry& index_entry = std::get<IndexEntry>(module_entry.tables[elem.mode.tableidx.value_or(0)]); |
| 240 | if(index_entry.kind == IndexEntry::Address){ |
| 241 | elem.mode.tableidx = index_entry.index + import_counter.table; |
| 242 | }else{ |
| 243 | elem.mode.tableidx = index_entry.index; |
| 244 | } |
| 245 | if(elem.mode.offset){ |
| 246 | instr_update_indices(elem.mode.offset.value(), module_entry); |
| 247 | } |
| 248 | } |
| 249 | // Datas |
| 250 | for(index_t data_idx = 0; data_idx < output.datas.size(); ++data_idx){ |
| 251 | WasmData& data = output.datas[data_idx]; |