From f154f511dd2979a16f3083f452f4a82996907cdc Mon Sep 17 00:00:00 2001 From: ddidderr Date: Tue, 21 Jul 2026 20:33:46 +0200 Subject: [PATCH] feat(decompress): call dictionary entropy loader from Rust The DDict implementation already owned the decoder-table loader in zstd_decompress.rs, but zstd_ddict.rs still declared it as an external C helper and disabled that path in Rust unit-test builds. Call the Rust implementation directly through the ABI-compatible entropy-table projection and make the module documentation match the actual ownership. Keep offset_of imported only for the non-test C-context projection so the Rust test check remains warning-free. Test Plan: - git diff --check - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo check --manifest-path rust/Cargo.toml --tests - Standalone cargo test was attempted; linking remains blocked by the existing C context-projection symbols used by the hybrid test crate. --- rust/src/zstd_ddict.rs | 45 +++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 29 deletions(-) diff --git a/rust/src/zstd_ddict.rs b/rust/src/zstd_ddict.rs index 43227130d..053a9d840 100644 --- a/rust/src/zstd_ddict.rs +++ b/rust/src/zstd_ddict.rs @@ -2,17 +2,17 @@ //! Digested decompression dictionaries (`ZSTD_DDict`). //! -//! The decoder proper is still implemented in C during the migration. In -//! particular, its `ZSTD_loadDEntropy()` helper owns the format-specific -//! construction of the decoder tables. This module owns the DDict object, -//! its allocation and lifetime, and passes an ABI-identical table layout to -//! that helper. +//! The decoder proper and its `ZSTD_loadDEntropy()` dictionary-table loader +//! are Rust-owned. This module owns the DDict object, its allocation and +//! lifetime, and passes an ABI-identical table layout to the decoder module. use crate::common::{LL_FSE_LOG, ML_FSE_LOG, OFF_FSE_LOG, ZSTD_FRAMEIDSIZE, ZSTD_REP_NUM}; use crate::errors::{ERR_isError, ZstdErrorCode, ERROR}; use crate::mem::MEM_readLE32; use std::ffi::c_void; -use std::mem::{offset_of, size_of}; +#[cfg(not(test))] +use std::mem::offset_of; +use std::mem::size_of; use std::os::raw::{c_int, c_uint}; use std::ptr; @@ -103,15 +103,6 @@ struct ZstdDctxOffsets { fuzz_end: usize, } -#[cfg(not(test))] -unsafe extern "C" { - fn ZSTD_loadDEntropy( - entropy: *mut ZSTD_entropyDTables, - dict: *const c_void, - dict_size: usize, - ) -> usize; -} - #[cfg(test)] #[inline] unsafe fn ddict_dctx_offsets() -> ZstdDctxOffsets { @@ -258,20 +249,16 @@ unsafe fn load_d_entropy( dict: *const c_void, dict_size: usize, ) -> usize { - #[cfg(not(test))] - { - // The existing C decoder owns this helper until its translation unit is - // moved. Its argument is the ABI-compatible table storage above. - unsafe { ZSTD_loadDEntropy(entropy, dict, dict_size) } - } - - #[cfg(test)] - { - let _ = (entropy, dict, dict_size); - // Unit tests exercise the DDict ownership and raw-content paths. A - // full dictionary is covered by the C compatibility executables, where - // the decoder's real ZSTD_loadDEntropy() is linked in. - ERROR(ZstdErrorCode::DictionaryCorrupted) + // The DDict and decoder modules keep separate Rust representations so + // neither needs to expose the other module's private fields. Both are + // `repr(C)` and guarded by exact layout assertions; only the pointer type + // changes at this narrow module boundary. + unsafe { + crate::zstd_decompress::ZSTD_loadDEntropy( + entropy.cast::(), + dict, + dict_size, + ) } }