@@ -1184,12 +1184,26 @@ pub(crate) extern "C" fn pd_vm_native_restore_active_sparse_exit_state(
11841184 vm. stack . push ( value) ;
11851185 }
11861186
1187- for compact_index in 0 ..dirty_local_count {
1188- let local_index = unsafe { * dirty_local_indices. add ( compact_index) } ;
1189- debug_assert ! ( u8 :: try_from( local_index) . is_ok( ) ) ;
1190- let local_index = local_index as u8 ;
1191- let value = unsafe { std:: ptr:: read ( dirty_local_values. add ( compact_index) ) } ;
1192- vm. store_local_with_drop_contract ( local_index, value) ?;
1187+ if vm. capture_cells . is_empty ( ) {
1188+ let local_base = vm. active_local_base ( ) ;
1189+ for compact_index in 0 ..dirty_local_count {
1190+ let local_index = unsafe { * dirty_local_indices. add ( compact_index) } as usize ;
1191+ debug_assert ! ( local_index < 256 ) ;
1192+ let absolute = local_base + local_index;
1193+ debug_assert ! ( absolute < vm. locals. len( ) ) ;
1194+ let value = unsafe { std:: ptr:: read ( dirty_local_values. add ( compact_index) ) } ;
1195+ let slot = unsafe { vm. locals . get_unchecked_mut ( absolute) } ;
1196+ let previous = std:: mem:: replace ( slot, value) ;
1197+ vm. drop_value_with_contract ( previous) ;
1198+ }
1199+ } else {
1200+ for compact_index in 0 ..dirty_local_count {
1201+ let local_index = unsafe { * dirty_local_indices. add ( compact_index) } ;
1202+ debug_assert ! ( u8 :: try_from( local_index) . is_ok( ) ) ;
1203+ let local_index = local_index as u8 ;
1204+ let value = unsafe { std:: ptr:: read ( dirty_local_values. add ( compact_index) ) } ;
1205+ vm. store_local_with_drop_contract ( local_index, value) ?;
1206+ }
11931207 }
11941208
11951209 if ip >= vm. program . code . len ( ) {
0 commit comments