feat(compress): move window clearing leaf into Rust
Keep the private ZSTD_window_t layout and pointer-difference calculation in C, then route the size_t-to-U32 conversion and paired limit writes through a small Rust ABI leaf. This removes the inline C window-clear implementation while preserving its overflow behavior at both single-threaded and multithreaded call sites. Test Plan: - cargo test --manifest-path rust/Cargo.toml --lib zstd_compress::tests (77 passed) - make -C programs -j2 zstd - rustfmt +nightly --edition 2021 rust/src/zstd_compress.rs --check - make -C tests -j2 test-cli-tests (41 passed) - make -C tests -j2 test-legacy test-invalidDictionaries test-decodecorpus test-rust-lib-smoke (passed) - git diff --check
This commit is contained in:
@@ -859,6 +859,24 @@ pub unsafe extern "C" fn ZSTD_rust_invalidateRepCodes(rep: *mut u32) {
|
||||
rep.fill(0);
|
||||
}
|
||||
|
||||
/// Clear a C-owned compression window using the original `size_t`-to-`U32`
|
||||
/// conversion. The caller computes the pointer difference while the private
|
||||
/// `ZSTD_window_t` layout remains entirely on the C side.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ZSTD_rust_windowClear(
|
||||
end_t: usize,
|
||||
low_limit: *mut u32,
|
||||
dict_limit: *mut u32,
|
||||
) {
|
||||
debug_assert!(!low_limit.is_null());
|
||||
debug_assert!(!dict_limit.is_null());
|
||||
let end = end_t as u32;
|
||||
unsafe {
|
||||
*low_limit = end;
|
||||
*dict_limit = end;
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn zeroed_state() -> ZSTD_compressedBlockState_t {
|
||||
/* The state contains only integer arrays and enum fields. */
|
||||
@@ -2146,6 +2164,30 @@ mod tests {
|
||||
assert_eq!(rep, [0; ZSTD_REP_NUM]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn window_clear_writes_the_same_end_to_both_limits() {
|
||||
let mut low_limit = 11u32;
|
||||
let mut dict_limit = 22u32;
|
||||
|
||||
unsafe { ZSTD_rust_windowClear(0x1234_5678, &mut low_limit, &mut dict_limit) };
|
||||
|
||||
assert_eq!(low_limit, 0x1234_5678);
|
||||
assert_eq!(dict_limit, 0x1234_5678);
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
#[test]
|
||||
fn window_clear_truncates_a_large_size_t_like_c_u32_cast() {
|
||||
let mut low_limit = 11u32;
|
||||
let mut dict_limit = 22u32;
|
||||
let end_t = 0x1_0000_0000usize + 0x89ab_cdef;
|
||||
|
||||
unsafe { ZSTD_rust_windowClear(end_t, &mut low_limit, &mut dict_limit) };
|
||||
|
||||
assert_eq!(low_limit, 0x89ab_cdef);
|
||||
assert_eq!(dict_limit, 0x89ab_cdef);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sizeof_local_dict_ignores_size_without_a_buffer() {
|
||||
assert_eq!(sizeof_local_dict(0, 37, 11), 11);
|
||||
|
||||
Reference in New Issue
Block a user