diff --git a/crates/compiler/gen_dev/src/generic64/aarch64.rs b/crates/compiler/gen_dev/src/generic64/aarch64.rs index b73a2699c7..010a0c9d18 100644 --- a/crates/compiler/gen_dev/src/generic64/aarch64.rs +++ b/crates/compiler/gen_dev/src/generic64/aarch64.rs @@ -1119,6 +1119,26 @@ impl Assembler for AArch64Assembler { buf.len() } + /// Updates a jump instruction to a new offset and returns the number of bytes written. + fn update_jmp_imm32_offset( + buf: &mut Vec<'_, u8>, + jmp_location: u64, + base_offset: u64, + target_offset: u64, + ) { + let old_buf_len = buf.len(); + + // write the jmp at the back of buf + let jmp_offset = target_offset as i32 - base_offset as i32 + 4; + Self::jmp_imm32(buf, jmp_offset); + + // move the new jmp instruction into position + buf.copy_within(old_buf_len.., jmp_location as usize); + + // wipe the jmp we created at the end + buf.truncate(old_buf_len) + } + #[inline(always)] fn tail_call(buf: &mut Vec<'_, u8>) -> u64 { Self::jmp_imm32(buf, 0); diff --git a/crates/compiler/gen_dev/src/generic64/mod.rs b/crates/compiler/gen_dev/src/generic64/mod.rs index 131a3c6704..026fa7f5e1 100644 --- a/crates/compiler/gen_dev/src/generic64/mod.rs +++ b/crates/compiler/gen_dev/src/generic64/mod.rs @@ -263,19 +263,7 @@ pub trait Assembler: Sized + Copy { jmp_location: u64, base_offset: u64, target_offset: u64, - ) { - let old_buf_len = buf.len(); - - // write the jmp at the back of buf - let jmp_offset = target_offset as i32 - base_offset as i32; - Self::jmp_imm32(buf, jmp_offset); - - // move the new jmp instruction into position - buf.copy_within(old_buf_len.., jmp_location as usize); - - // wipe the jmp we created at the end - buf.truncate(old_buf_len) - } + ); fn tail_call(buf: &mut Vec<'_, u8>) -> u64; diff --git a/crates/compiler/gen_dev/src/generic64/x86_64.rs b/crates/compiler/gen_dev/src/generic64/x86_64.rs index 8c567a23bf..dcfb26c904 100644 --- a/crates/compiler/gen_dev/src/generic64/x86_64.rs +++ b/crates/compiler/gen_dev/src/generic64/x86_64.rs @@ -2114,6 +2114,26 @@ impl Assembler for X86_64Assembler { buf.len() } + /// Updates a jump instruction to a new offset and returns the number of bytes written. + fn update_jmp_imm32_offset( + buf: &mut Vec<'_, u8>, + jmp_location: u64, + base_offset: u64, + target_offset: u64, + ) { + let old_buf_len = buf.len(); + + // write the jmp at the back of buf + let jmp_offset = target_offset as i32 - base_offset as i32; + Self::jmp_imm32(buf, jmp_offset); + + // move the new jmp instruction into position + buf.copy_within(old_buf_len.., jmp_location as usize); + + // wipe the jmp we created at the end + buf.truncate(old_buf_len) + } + #[inline(always)] fn tail_call(buf: &mut Vec<'_, u8>) -> u64 { Self::jmp_imm32(buf, 0);