From 094ec8dd8a540975a8cce70742aa4b78497ec352 Mon Sep 17 00:00:00 2001 From: Ivan Gankevich Date: Thu, 26 Jun 2025 13:43:32 +0200 Subject: [PATCH 1/5] Fix instruction length calculation. --- crates/polkavm/src/compiler.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/crates/polkavm/src/compiler.rs b/crates/polkavm/src/compiler.rs index 0d83c2b0..937faf7f 100644 --- a/crates/polkavm/src/compiler.rs +++ b/crates/polkavm/src/compiler.rs @@ -115,6 +115,7 @@ where memset_trampoline_start: usize, memset_trampoline_end: usize, custom_codegen: Option>, + asm_len_before: usize, _phantom: PhantomData<(S, B)>, } @@ -260,6 +261,7 @@ where memset_trampoline_start: 0, memset_trampoline_end: 0, custom_codegen: config.custom_codegen.clone(), + asm_len_before: 0, _phantom: PhantomData, }; @@ -454,18 +456,20 @@ where } } - fn before_instruction(&self, program_counter: u32) { + fn before_instruction(&mut self, program_counter: u32) { if log::log_enabled!(log::Level::Trace) { self.trace_compiled_instruction(program_counter); } + if cfg!(debug_assertions) && !self.step_tracing && self.custom_codegen.is_none() { + self.asm_len_before = self.asm.len(); + } } fn after_instruction(&mut self, program_counter: u32, args_length: u32) { assert!(KIND == CONTINUE_BASIC_BLOCK || KIND == END_BASIC_BLOCK || KIND == END_BASIC_BLOCK_INVALID); if cfg!(debug_assertions) && !self.step_tracing && self.custom_codegen.is_none() { - let offset = self.program_counter_to_machine_code_offset_list.last().unwrap().1 as usize; - let instruction_length = self.asm.len() - offset; + let instruction_length = self.asm.len() - self.asm_len_before; if instruction_length > VM_COMPILER_MAXIMUM_INSTRUCTION_LENGTH as usize { self.panic_on_too_long_instruction(program_counter, instruction_length) } From 8fbc2869ab3a836a8abc6661bfaa42672eb818cf Mon Sep 17 00:00:00 2001 From: Ivan Gankevich Date: Thu, 26 Jun 2025 14:34:18 +0200 Subject: [PATCH 2/5] Add instruction length calculation test. --- crates/polkavm/src/tests.rs | 74 ++++++++++++++++---------- guest-programs/test-blob/src/common.rs | 18 ++++++- 2 files changed, 63 insertions(+), 29 deletions(-) diff --git a/crates/polkavm/src/tests.rs b/crates/polkavm/src/tests.rs index bd660cdb..490426b2 100644 --- a/crates/polkavm/src/tests.rs +++ b/crates/polkavm/src/tests.rs @@ -1,6 +1,6 @@ use crate::mutex::Mutex; use crate::{ - BackendKind, CallError, Caller, Config, Engine, GasMeteringKind, InterruptKind, Linker, MemoryAccessError, Module, ModuleConfig, + BackendKind, CallError, Caller, Config, Engine, Gas, GasMeteringKind, InterruptKind, Linker, MemoryAccessError, Module, ModuleConfig, ProgramBlob, ProgramCounter, Reg, Segfault, }; use alloc::collections::BTreeMap; @@ -2648,12 +2648,12 @@ struct TestInstance { } impl TestInstance { - fn new(config: &Config, elf: &'static [u8], optimize: bool) -> Self { + fn new(config: &Config, module_config: &ModuleConfig, elf: &'static [u8], optimize: bool) -> Self { let _ = env_logger::try_init(); let blob = get_blob_impl(optimize, false, elf); let engine = Engine::new(config).unwrap(); - let module = Module::from_blob(&engine, &Default::default(), blob).unwrap(); + let module = Module::from_blob(&engine, module_config, blob).unwrap(); let mut linker = Linker::new(); linker .define_typed("multiply_by_2", |_caller: Caller<()>, value: u32| -> u32 { value * 2 }) @@ -2750,7 +2750,7 @@ impl TestBlobArgs { fn test_blob_basic_test(args: TestBlobArgs) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); assert_eq!(i.call::<(), u32>("push_one_to_global_vec", ()).unwrap(), 1); assert_eq!(i.call::<(), u32>("push_one_to_global_vec", ()).unwrap(), 2); assert_eq!(i.call::<(), u32>("push_one_to_global_vec", ()).unwrap(), 3); @@ -2758,7 +2758,7 @@ fn test_blob_basic_test(args: TestBlobArgs) { fn test_blob_atomic_fetch_add(args: TestBlobArgs) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); assert_eq!(i.call::<(u32,), u32>("atomic_fetch_add", (1,)).unwrap(), 0); assert_eq!(i.call::<(u32,), u32>("atomic_fetch_add", (1,)).unwrap(), 1); assert_eq!(i.call::<(u32,), u32>("atomic_fetch_add", (1,)).unwrap(), 2); @@ -2770,7 +2770,7 @@ fn test_blob_atomic_fetch_add(args: TestBlobArgs) { fn test_blob_atomic_fetch_swap(args: TestBlobArgs) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); assert_eq!(i.call::<(u32,), u32>("atomic_fetch_swap", (10,)).unwrap(), 0); assert_eq!(i.call::<(u32,), u32>("atomic_fetch_swap", (100,)).unwrap(), 10); assert_eq!(i.call::<(u32,), u32>("atomic_fetch_swap", (1000,)).unwrap(), 100); @@ -2799,7 +2799,7 @@ fn test_blob_atomic_fetch_minmax(args: TestBlobArgs) { ]; let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); for (name, cb) in list { for a in [-10, 0, 10] { for b in [-10, 0, 10] { @@ -2814,19 +2814,19 @@ fn test_blob_atomic_fetch_minmax(args: TestBlobArgs) { fn test_blob_hostcall(args: TestBlobArgs) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); assert_eq!(i.call::<(u32,), u32>("test_multiply_by_6", (10,)).unwrap(), 60); } fn test_blob_define_abi(args: TestBlobArgs) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); assert!(i.call::<(), ()>("test_define_abi", ()).is_ok()); } fn test_blob_input_registers(args: TestBlobArgs) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); assert!(i.call::<(), ()>("test_input_registers", ()).is_ok()); } @@ -2844,7 +2844,7 @@ fn test_blob_call_sbrk_from_host_function(args: TestBlobArgs) { fn test_blob_program_memory_can_be_reused_and_cleared(args: TestBlobArgs) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); let address = i.call::<(), u32>("get_global_address", ()).unwrap(); assert_eq!(i.instance.read_memory(address, 4).unwrap(), [0x00, 0x00, 0x00, 0x00]); @@ -2864,7 +2864,7 @@ fn test_blob_program_memory_can_be_reused_and_cleared(args: TestBlobArgs) { fn test_blob_out_of_bounds_memory_access_generates_a_trap(args: TestBlobArgs) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); let address = i.call::<(), u32>("get_global_address", ()).unwrap(); assert_eq!(i.call::<(u32,), u32>("read_u32", (address,)).unwrap(), 0); i.call::<(), ()>("increment_global", ()).unwrap(); @@ -2878,7 +2878,7 @@ fn test_blob_out_of_bounds_memory_access_generates_a_trap(args: TestBlobArgs) { fn test_blob_call_sbrk_impl(args: TestBlobArgs, mut call_sbrk: impl FnMut(&mut TestInstance, u32) -> u32) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); let memory_map = i.module.memory_map().clone(); let heap_base = memory_map.heap_base(); let page_size = memory_map.page_size(); @@ -2934,7 +2934,7 @@ fn test_blob_call_sbrk_impl(args: TestBlobArgs, mut call_sbrk: impl FnMut(&mut T fn test_blob_add_u32(args: TestBlobArgs) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); assert_eq!(i.call::<(u32, u32), u32>("add_u32", (1, 2,)).unwrap(), 3); assert_eq!(i.instance.reg(Reg::A0), 3); @@ -2952,7 +2952,7 @@ fn test_blob_add_u32(args: TestBlobArgs) { fn test_blob_add_u64(args: TestBlobArgs) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); assert_eq!(i.call::<(u64, u64), u64>("add_u64", (1, 2,)).unwrap(), 3); assert_eq!(i.instance.reg(Reg::A0), 3); assert_eq!( @@ -2963,7 +2963,7 @@ fn test_blob_add_u64(args: TestBlobArgs) { fn test_blob_xor_imm_u32(args: TestBlobArgs) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); for value in [0, 0xaaaaaaaa, 0x55555555, 0x12345678, 0xffffffff] { assert_eq!(i.call::<(u32,), u32>("xor_imm_u32", (value,)).unwrap(), value ^ 0xfb8f5c1e); } @@ -2971,13 +2971,13 @@ fn test_blob_xor_imm_u32(args: TestBlobArgs) { fn test_blob_branch_less_than_zero(args: TestBlobArgs) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); i.call::<(), ()>("test_branch_less_than_zero", ()).unwrap(); } fn test_blob_fetch_add_atomic_u64(args: TestBlobArgs) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); assert_eq!(i.call::<(u64,), u64>("fetch_add_atomic_u64", (1,)).unwrap(), 0); assert_eq!(i.call::<(u64,), u64>("fetch_add_atomic_u64", (0,)).unwrap(), 1); assert_eq!(i.call::<(u64,), u64>("fetch_add_atomic_u64", (0,)).unwrap(), 1); @@ -2987,25 +2987,25 @@ fn test_blob_fetch_add_atomic_u64(args: TestBlobArgs) { fn test_blob_cmov_if_zero_with_zero_reg(args: TestBlobArgs) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); i.call::<(), ()>("cmov_if_zero_with_zero_reg", ()).unwrap(); } fn test_blob_cmov_if_not_zero_with_zero_reg(args: TestBlobArgs) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); i.call::<(), ()>("cmov_if_not_zero_with_zero_reg", ()).unwrap(); } fn test_blob_min_stack_size(args: TestBlobArgs) { let elf = args.get_test_program(); - let i = TestInstance::new(&args.config, elf, args.optimize); + let i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); assert_eq!(i.instance.module().memory_map().stack_size(), 65536); } fn test_blob_negate_and_add(args: TestBlobArgs) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); if !args.is_64_bit { assert_eq!(i.call::<(u32, u32), u32>("negate_and_add", (123, 1,)).unwrap(), 15); } else { @@ -3015,13 +3015,13 @@ fn test_blob_negate_and_add(args: TestBlobArgs) { fn test_blob_return_tuple_from_import(args: TestBlobArgs) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); i.call::<(), ()>("test_return_tuple", ()).unwrap(); } fn test_blob_return_tuple_from_export(args: TestBlobArgs) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); if args.is_64_bit { let a0 = 0x123456789abcdefe_u64; let a1 = 0x1122334455667788_u64; @@ -3051,23 +3051,40 @@ fn test_blob_return_tuple_from_export(args: TestBlobArgs) { fn test_blob_get_heap_base(args: TestBlobArgs) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); let heap_base = i.call::<(), u32>("get_heap_base", ()).unwrap(); assert_eq!(heap_base, i.instance.module().memory_map().heap_base()); } fn test_blob_get_self_address(args: TestBlobArgs) { let elf = args.get_test_program(); - let mut i = TestInstance::new(&args.config, elf, args.optimize); + let mut i = TestInstance::new(&args.config, &Default::default(), elf, args.optimize); let addr = i.call::<(), u32>("get_self_address", ()).unwrap(); assert_ne!(addr, 0); } +fn test_blob_instruction_length(args: TestBlobArgs) { + // Test that the instruction length is properly calculated when gas metering is enabled and a + // long instruction appears at the start of the block (right after gas metering stub). + let elf = args.get_test_program(); + let mut module_config = ModuleConfig::default(); + module_config.set_gas_metering(Some(GasMeteringKind::Sync)); + let mut i = TestInstance::new(&args.config, &module_config, elf, args.optimize); + i.instance.set_gas(Gas::MAX); + if args.is_64_bit { + assert_eq!(i.call::<(u64, u64), u64>("div_asm", (10, 2,)).unwrap(), 5); + assert_eq!(i.instance.reg(Reg::A0), 5); + } else { + assert_eq!(i.call::<(u32, u32), u32>("div_asm", (10, 2,)).unwrap(), 5); + assert_eq!(i.instance.reg(Reg::A0), 5); + } +} + fn test_asm_reloc_add_sub(config: Config, optimize: bool) { const BLOB_64: &[u8] = include_bytes!("../../../guest-programs/asm-tests/output/reloc_add_sub_64.elf"); let elf = BLOB_64; - let mut i = TestInstance::new(&config, elf, optimize); + let mut i = TestInstance::new(&config, &Default::default(), elf, optimize); let address = i.call::<(u32,), u32>("get_string", (0,)).unwrap(); assert_eq!(i.instance.read_u32(address).unwrap(), 0x01010101); @@ -3083,7 +3100,7 @@ fn test_asm_reloc_hi_lo(config: Config, optimize: bool) { const BLOB_64: &[u8] = include_bytes!("../../../guest-programs/asm-tests/output/reloc_hi_lo_64.elf"); let elf = BLOB_64; - let mut i = TestInstance::new(&config, elf, optimize); + let mut i = TestInstance::new(&config, &Default::default(), elf, optimize); let address = i.call::<(u32,), u32>("get_string", (0,)).unwrap(); assert_eq!(i.instance.read_u32(address).unwrap(), 0xA1010101); @@ -3897,6 +3914,7 @@ run_test_blob_tests! { test_blob_return_tuple_from_export test_blob_get_heap_base test_blob_get_self_address + test_blob_instruction_length } run_asm_tests! { diff --git a/guest-programs/test-blob/src/common.rs b/guest-programs/test-blob/src/common.rs index 46a3c889..7d091820 100644 --- a/guest-programs/test-blob/src/common.rs +++ b/guest-programs/test-blob/src/common.rs @@ -428,7 +428,9 @@ extern "C" fn get_heap_base() -> u32 { #[inline(never)] fn get_self_address_impl() -> usize { - unsafe { GLOBAL += 1; } + unsafe { + GLOBAL += 1; + } get_self_address_impl as usize } @@ -436,3 +438,17 @@ fn get_self_address_impl() -> usize { extern "C" fn get_self_address() -> u32 { get_self_address_impl() as u32 } + +#[polkavm_derive::polkavm_export] +extern "C" fn div_asm(a0: usize, a1: usize) -> usize { + unsafe { + let output; + core::arch::asm!( + "div a0, a0, a1", + in("a0") a0, + in("a1") a1, + lateout("a0") output, + ); + output + } +} From 5db45a2488c39c4cd528ee86a82b1881bd884056 Mon Sep 17 00:00:00 2001 From: Ivan Gankevich Date: Fri, 11 Jul 2025 15:34:57 +0200 Subject: [PATCH 3/5] Move `if` to the end of `after_instruction`. --- crates/polkavm/src/compiler.rs | 22 +++++++++------------- guest-programs/test-blob/src/common.rs | 4 +--- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/crates/polkavm/src/compiler.rs b/crates/polkavm/src/compiler.rs index 937faf7f..60c2f0e9 100644 --- a/crates/polkavm/src/compiler.rs +++ b/crates/polkavm/src/compiler.rs @@ -115,7 +115,6 @@ where memset_trampoline_start: usize, memset_trampoline_end: usize, custom_codegen: Option>, - asm_len_before: usize, _phantom: PhantomData<(S, B)>, } @@ -261,7 +260,6 @@ where memset_trampoline_start: 0, memset_trampoline_end: 0, custom_codegen: config.custom_codegen.clone(), - asm_len_before: 0, _phantom: PhantomData, }; @@ -456,25 +454,15 @@ where } } - fn before_instruction(&mut self, program_counter: u32) { + fn before_instruction(&self, program_counter: u32) { if log::log_enabled!(log::Level::Trace) { self.trace_compiled_instruction(program_counter); } - if cfg!(debug_assertions) && !self.step_tracing && self.custom_codegen.is_none() { - self.asm_len_before = self.asm.len(); - } } fn after_instruction(&mut self, program_counter: u32, args_length: u32) { assert!(KIND == CONTINUE_BASIC_BLOCK || KIND == END_BASIC_BLOCK || KIND == END_BASIC_BLOCK_INVALID); - if cfg!(debug_assertions) && !self.step_tracing && self.custom_codegen.is_none() { - let instruction_length = self.asm.len() - self.asm_len_before; - if instruction_length > VM_COMPILER_MAXIMUM_INSTRUCTION_LENGTH as usize { - self.panic_on_too_long_instruction(program_counter, instruction_length) - } - } - let next_program_counter = program_counter + args_length + 1; self.program_counter_to_machine_code_offset_list .push((ProgramCounter(next_program_counter), self.asm.len() as u32)); @@ -491,6 +479,14 @@ where } else if self.step_tracing { self.step(next_program_counter); } + + if cfg!(debug_assertions) && !self.step_tracing && self.custom_codegen.is_none() { + let offset = self.program_counter_to_machine_code_offset_list.last().unwrap().1 as usize; + let instruction_length = self.asm.len() - offset; + if instruction_length > VM_COMPILER_MAXIMUM_INSTRUCTION_LENGTH as usize { + self.panic_on_too_long_instruction(program_counter, instruction_length) + } + } } #[inline(never)] diff --git a/guest-programs/test-blob/src/common.rs b/guest-programs/test-blob/src/common.rs index f6f9ea2f..1ec5bb2a 100644 --- a/guest-programs/test-blob/src/common.rs +++ b/guest-programs/test-blob/src/common.rs @@ -428,9 +428,7 @@ extern "C" fn get_heap_base() -> u32 { #[inline(never)] fn get_self_address_impl() -> usize { - unsafe { - GLOBAL += 1; - } + unsafe { GLOBAL += 1; } get_self_address_impl as usize } From c70ad4a2e007d39ce5839d81b6d7cb32db5c9c2c Mon Sep 17 00:00:00 2001 From: Ivan Gankevich Date: Fri, 11 Jul 2025 15:55:45 +0200 Subject: [PATCH 4/5] Move `if` back. Increase max. instruction length by 10. --- crates/polkavm-common/src/zygote.rs | 4 ++-- crates/polkavm/src/compiler.rs | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/polkavm-common/src/zygote.rs b/crates/polkavm-common/src/zygote.rs index d491a7b4..3d6346f1 100644 --- a/crates/polkavm-common/src/zygote.rs +++ b/crates/polkavm-common/src/zygote.rs @@ -124,7 +124,7 @@ pub const VM_SHARED_MEMORY_SIZE: u64 = u32::MAX as u64; /// /// This does *not* affect the VM ABI and can be changed at will, /// but should be high enough that it's never hit. -pub const VM_COMPILER_MAXIMUM_INSTRUCTION_LENGTH: u32 = 67; +pub const VM_COMPILER_MAXIMUM_INSTRUCTION_LENGTH: u32 = 77; /// The maximum number of bytes the jump table can be. pub const VM_SANDBOX_MAXIMUM_JUMP_TABLE_SIZE: u64 = (crate::abi::VM_MAXIMUM_JUMP_TABLE_ENTRIES as u64 + 1) @@ -136,7 +136,7 @@ pub const VM_SANDBOX_MAXIMUM_JUMP_TABLE_VIRTUAL_SIZE: u64 = 0x100000000 * core:: // TODO: Make this smaller. /// The maximum number of bytes the native code can be. -pub const VM_SANDBOX_MAXIMUM_NATIVE_CODE_SIZE: u32 = 2176 * 1024 * 1024 - 1; +pub const VM_SANDBOX_MAXIMUM_NATIVE_CODE_SIZE: u32 = 32 * (77 + 1) * 1024 * 1024 - 1; #[repr(C)] pub struct JmpBuf { diff --git a/crates/polkavm/src/compiler.rs b/crates/polkavm/src/compiler.rs index 60c2f0e9..0d83c2b0 100644 --- a/crates/polkavm/src/compiler.rs +++ b/crates/polkavm/src/compiler.rs @@ -463,6 +463,14 @@ where fn after_instruction(&mut self, program_counter: u32, args_length: u32) { assert!(KIND == CONTINUE_BASIC_BLOCK || KIND == END_BASIC_BLOCK || KIND == END_BASIC_BLOCK_INVALID); + if cfg!(debug_assertions) && !self.step_tracing && self.custom_codegen.is_none() { + let offset = self.program_counter_to_machine_code_offset_list.last().unwrap().1 as usize; + let instruction_length = self.asm.len() - offset; + if instruction_length > VM_COMPILER_MAXIMUM_INSTRUCTION_LENGTH as usize { + self.panic_on_too_long_instruction(program_counter, instruction_length) + } + } + let next_program_counter = program_counter + args_length + 1; self.program_counter_to_machine_code_offset_list .push((ProgramCounter(next_program_counter), self.asm.len() as u32)); @@ -479,14 +487,6 @@ where } else if self.step_tracing { self.step(next_program_counter); } - - if cfg!(debug_assertions) && !self.step_tracing && self.custom_codegen.is_none() { - let offset = self.program_counter_to_machine_code_offset_list.last().unwrap().1 as usize; - let instruction_length = self.asm.len() - offset; - if instruction_length > VM_COMPILER_MAXIMUM_INSTRUCTION_LENGTH as usize { - self.panic_on_too_long_instruction(program_counter, instruction_length) - } - } } #[inline(never)] From d22fae3c56a2fd76dd16a2dbf3830ee2f2a99bba Mon Sep 17 00:00:00 2001 From: Ivan Gankevich Date: Fri, 11 Jul 2025 17:25:17 +0200 Subject: [PATCH 5/5] Disable `wasm3` feature of `benchtool`. --- tools/benchtool/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/benchtool/Cargo.toml b/tools/benchtool/Cargo.toml index 5af34716..cb5d4325 100644 --- a/tools/benchtool/Cargo.toml +++ b/tools/benchtool/Cargo.toml @@ -34,7 +34,6 @@ default = [ "native", "pvf-executor", "solana_rbpf", - "wasm3", "wasmer", "wasmi", "wasmtime",