diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 278b1925c..8c7819947 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -269,6 +269,9 @@ size_t ZSTD_rust_copyBlockSequences( SeqCollector* seqCollector, const SeqStore_t* seqStore, const U32 prevRepcodes[ZSTD_REP_NUM]); void ZSTD_rust_resetCompressedBlockState(ZSTD_compressedBlockState_t* bs); +void ZSTD_rust_confirmRepcodesAndEntropyTables( + ZSTD_compressedBlockState_t** prevCBlock, + ZSTD_compressedBlockState_t** nextCBlock); void ZSTD_rust_storeLastLiterals(SeqStore_t* seqStorePtr, const BYTE* anchor, size_t lastLLSize); void ZSTD_rust_resetSeqStore(SeqStore_t* ssPtr); @@ -2596,9 +2599,8 @@ static int ZSTD_maybeRLE(SeqStore_t const* seqStore) static void ZSTD_blockState_confirmRepcodesAndEntropyTables(ZSTD_blockState_t* const bs) { - ZSTD_compressedBlockState_t* const tmp = bs->prevCBlock; - bs->prevCBlock = bs->nextCBlock; - bs->nextCBlock = tmp; + ZSTD_rust_confirmRepcodesAndEntropyTables( + &bs->prevCBlock, &bs->nextCBlock); } /* Writes the block header */ diff --git a/rust/src/zstd_compress_stats.rs b/rust/src/zstd_compress_stats.rs index 160466f16..53fc13948 100644 --- a/rust/src/zstd_compress_stats.rs +++ b/rust/src/zstd_compress_stats.rs @@ -1095,6 +1095,18 @@ pub unsafe extern "C" fn ZSTD_rust_resetCompressedBlockState( block_state.entropy.fse.litlength_repeatMode = FSE_REPEAT_NONE; } +/// Swaps the two C-owned block-state pointers after a block is confirmed. +/// +/// The enclosing `ZSTD_blockState_t` contains C-only match-state storage, so +/// the ABI deliberately passes only the two pointer fields separately. +#[no_mangle] +pub unsafe extern "C" fn ZSTD_rust_confirmRepcodesAndEntropyTables( + prev_c_block: *mut *mut ZSTD_compressedBlockState_t, + next_c_block: *mut *mut ZSTD_compressedBlockState_t, +) { + unsafe { ptr::swap(prev_c_block, next_c_block) }; +} + /// Appends the final literals of a block to its sequence store. /// /// The source and destination ranges must be valid and non-overlapping, as @@ -3258,6 +3270,23 @@ mod tests { ); } + #[test] + fn confirm_repcodes_and_entropy_tables_swaps_block_state_pointers() { + let mut previous_storage = std::mem::MaybeUninit::::uninit(); + let mut next_storage = std::mem::MaybeUninit::::uninit(); + let previous = previous_storage.as_mut_ptr(); + let next = next_storage.as_mut_ptr(); + let mut previous_ptr = previous; + let mut next_ptr = next; + + unsafe { + ZSTD_rust_confirmRepcodesAndEntropyTables(&mut previous_ptr, &mut next_ptr); + } + + assert_eq!(previous_ptr, next); + assert_eq!(next_ptr, previous); + } + #[test] fn store_last_literals_copies_bytes_and_advances_only_the_literal_cursor() { let mut sequences = [SeqDef::default(); 2];