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.
This commit is contained in:
2026-07-21 20:33:46 +02:00
parent 073f198c53
commit f154f511dd
+16 -29
View File
@@ -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::<crate::zstd_decompress::ZSTD_entropyDTables_t>(),
dict,
dict_size,
)
}
}