walrus
walrus copied to clipboard
How to replace one instruction with a block
Summary
We can use visit_instr_mut to easily replace one instruction with another instruction. But how to replace the instruction with a block? It seems there is no direct way of creating InstrSeqBuilder, and I need to use FunctionBuilder and dangling_instr_seq. The following code compiles, but got a runtime error. Any help?
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `30`,
right: `387`', /.../walrus-0.19.0/src/module/functions/local_function/mod.rs:109:14
[Update] I can create a new function, and replace the instruction to call the new function. Is this an expected pattern, or there is a better way?
Additional Details
struct Replacer<'a> {
types: &'a mut ModuleTypes,
func_id: FunctionId,
}
impl<'a> ir::VisitorMut for Replacer<'a> {
fn visit_instr_mut(&mut self, instr: &mut ir::Instr, _instr_loc: &mut ir::InstrLocId) {
if let ir::Instr::Call(ir::Call { func }) = instr {
if *func == self.func_id {
let mut builder = FunctionBuilder::new(self.types, &[], &[]);
let mut seq = builder.dangling_instr_seq(None);
seq.drop().i32_const(...).call(...);
*instr = ir::Block { seq: seq.id() }.into();
}
}
}
}