(instructions: &mut Vec<Instruction>, function_data: &mut WasmFunctionData)
| 865 | } |
| 866 | |
| 867 | fn remove_nop(instructions: &mut Vec<Instruction>, function_data: &mut WasmFunctionData) { |
| 868 | let old_len = instructions.len(); |
| 869 | if old_len == 0 { |
| 870 | return; |
| 871 | } |
| 872 | |
| 873 | let mut removed_before = Vec::with_capacity(old_len + 1); |
| 874 | removed_before.push(0u32); |
| 875 | instructions.iter().for_each(|instr| { |
| 876 | let removed = removed_before.last().copied().unwrap_or(0) |
| 877 | + u32::from(matches!(instr, Instruction::Nop | Instruction::MergeBarrier)); |
| 878 | removed_before.push(removed); |
| 879 | }); |
| 880 | |
| 881 | let removed_total = removed_before[old_len]; |
| 882 | if removed_total == 0 { |
| 883 | return; |
| 884 | } |
| 885 | |
| 886 | let compacted_len = old_len as u32 - removed_total; |
| 887 | |
| 888 | function_data.branch_table_targets.iter_mut().for_each(|ip| { |
| 889 | let old_target = *ip as usize; |
| 890 | if old_target <= old_len { |
| 891 | *ip -= removed_before[old_target]; |
| 892 | debug_assert!(*ip < compacted_len, "remapped jump target points past end of function"); |
| 893 | } |
| 894 | }); |
| 895 | |
| 896 | instructions.retain_mut(|instr| { |
| 897 | let ip = match instr { |
| 898 | Instruction::Jump(ip) |
| 899 | | Instruction::JumpIfZero32(ip) |
| 900 | | Instruction::JumpIfNonZero32(ip) |
| 901 | | Instruction::JumpIfZero64(ip) |
| 902 | | Instruction::JumpIfNonZero64(ip) |
| 903 | | Instruction::JumpIfLocalZero32 { target_ip: ip, .. } |
| 904 | | Instruction::JumpIfLocalNonZero32 { target_ip: ip, .. } |
| 905 | | Instruction::JumpIfLocalZero64 { target_ip: ip, .. } |
| 906 | | Instruction::JumpIfLocalNonZero64 { target_ip: ip, .. } |
| 907 | | Instruction::JumpCmpStackConst32 { target_ip: ip, .. } |
| 908 | | Instruction::JumpCmpStackConst64 { target_ip: ip, .. } |
| 909 | | Instruction::JumpCmpLocalConst32 { target_ip: ip, .. } |
| 910 | | Instruction::JumpCmpLocalConst64 { target_ip: ip, .. } |
| 911 | | Instruction::JumpCmpLocalLocal32 { target_ip: ip, .. } |
| 912 | | Instruction::JumpCmpLocalLocal64 { target_ip: ip, .. } |
| 913 | | Instruction::BranchTable(ip, _, _) => ip, |
| 914 | _ => return !matches!(instr, Instruction::Nop | Instruction::MergeBarrier), |
| 915 | }; |
| 916 | |
| 917 | let old_target = *ip as usize; |
| 918 | if old_target > old_len { |
| 919 | return !matches!(instr, Instruction::Nop | Instruction::MergeBarrier); |
| 920 | } |
| 921 | |
| 922 | *ip -= removed_before[old_target]; |
| 923 | debug_assert!(*ip < compacted_len, "remapped jump target points past end of function"); |
| 924 | !matches!(instr, Instruction::Nop | Instruction::MergeBarrier) |
no test coverage detected