| 1323 | } |
| 1324 | |
| 1325 | void N64Recomp::LiveGenerator::emit_function_end() const { |
| 1326 | // Check that all jumps have been paired to a label. |
| 1327 | if (!context->pending_jumps.empty()) { |
| 1328 | assert(false); |
| 1329 | errored = true; |
| 1330 | } |
| 1331 | |
| 1332 | // Populate the labels for pending switches and move them into the unlinked jump tables. |
| 1333 | bool invalid_switch = false; |
| 1334 | for (size_t switch_index = 0; switch_index < context->switch_jump_labels.size(); switch_index++) { |
| 1335 | const std::vector<std::string>& cur_labels = context->switch_jump_labels[switch_index]; |
| 1336 | std::vector<sljit_label*> cur_label_addrs{}; |
| 1337 | cur_label_addrs.resize(cur_labels.size()); |
| 1338 | for (size_t case_index = 0; case_index < cur_labels.size(); case_index++) { |
| 1339 | // Find the label. |
| 1340 | auto find_it = context->labels.find(cur_labels[case_index]); |
| 1341 | if (find_it == context->labels.end()) { |
| 1342 | // Label not found, invalid switch. |
| 1343 | // Track this in a variable instead of returning immediately so that the pending labels are still cleared. |
| 1344 | invalid_switch = true; |
| 1345 | break; |
| 1346 | } |
| 1347 | cur_label_addrs[case_index] = find_it->second; |
| 1348 | } |
| 1349 | context->unlinked_jump_tables.emplace_back( |
| 1350 | std::make_pair<std::vector<sljit_label*>, std::unique_ptr<void*[]>>( |
| 1351 | std::move(cur_label_addrs), |
| 1352 | std::move(context->pending_jump_tables[switch_index]) |
| 1353 | ) |
| 1354 | ); |
| 1355 | } |
| 1356 | context->switch_jump_labels.clear(); |
| 1357 | context->pending_jump_tables.clear(); |
| 1358 | |
| 1359 | // Clear the labels to prevent labels from one function being jumped to by another. |
| 1360 | context->labels.clear(); |
| 1361 | |
| 1362 | if (invalid_switch) { |
| 1363 | assert(false); |
| 1364 | errored = true; |
| 1365 | } |
| 1366 | } |
| 1367 | |
| 1368 | void N64Recomp::LiveGenerator::emit_function_call_lookup(uint32_t addr) const { |
| 1369 | // Load the address immediate into the first argument. |
nothing calls this directly
no outgoing calls
no test coverage detected