feat(decompress): move block decoder wrappers into Rust

Move the hidden fullbench block-decoder entrypoints and the public
ZSTD_decompressBlock compatibility wrapper into Rust. The C translation unit
now only projects the configuration-dependent private DCtx fields into the
Rust block context, preserving the existing ABI and decoder feature modes.

Test Plan:
- cargo test --manifest-path rust/Cargo.toml --all-targets -- --test-threads=1
- cargo clippy --manifest-path rust/Cargo.toml --tests -- -D warnings
- make -B -C lib -j2 lib
- make -B -C tests -j2 test-rust-lib-smoke
- make -B -C tests -j2 test-cli-tests
This commit is contained in:
2026-07-18 23:46:08 +02:00
parent dc95de5212
commit 440585995b
2 changed files with 94 additions and 67 deletions
+7 -67
View File
@@ -102,73 +102,13 @@ static ZSTD_rustBlockCtx ZSTD_rust_block_context(ZSTD_DCtx* dctx)
return ctx;
}
size_t ZSTD_rust_decodeLiteralsBlock_wrapper(
ZSTD_rustBlockCtx* ctx,
const void* src, size_t srcSize,
void* dst, size_t dstCapacity);
size_t ZSTD_rust_decodeSeqHeaders(
ZSTD_rustBlockCtx* ctx, int* nbSeqPtr,
const void* src, size_t srcSize);
size_t ZSTD_rust_decompressBlock_internal(
ZSTD_rustBlockCtx* ctx,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize, int streaming);
void ZSTD_rust_checkContinuity(
ZSTD_rustBlockCtx* ctx, const void* dst, size_t dstSize);
size_t ZSTD_rust_decompressBlock_deprecated(
ZSTD_rustBlockCtx* ctx,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize);
/* Rust owns the hidden fullbench wrappers, the block decoder's internal
* entrypoints, and the public ZSTD_decompressBlock ABI. Keep only this
* private-context projection in C: the layout is configuration-dependent and
* must continue to be assembled next to ZSTD_DCtx. */
void ZSTD_rust_block_context_init(ZSTD_rustBlockCtx* out, ZSTD_DCtx* dctx);
/* Hidden declaration for fullbench. */
size_t ZSTD_decodeLiteralsBlock_wrapper(ZSTD_DCtx* dctx,
const void* src, size_t srcSize,
void* dst, size_t dstCapacity);
size_t ZSTD_decodeLiteralsBlock_wrapper(ZSTD_DCtx* dctx,
const void* src, size_t srcSize,
void* dst, size_t dstCapacity)
void ZSTD_rust_block_context_init(ZSTD_rustBlockCtx* out, ZSTD_DCtx* dctx)
{
ZSTD_rustBlockCtx ctx = ZSTD_rust_block_context(dctx);
return ZSTD_rust_decodeLiteralsBlock_wrapper(
&ctx, src, srcSize, dst, dstCapacity);
}
size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
const void* src, size_t srcSize)
{
ZSTD_rustBlockCtx ctx = ZSTD_rust_block_context(dctx);
return ZSTD_rust_decodeSeqHeaders(&ctx, nbSeqPtr, src, srcSize);
}
size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize,
const streaming_operation streaming)
{
ZSTD_rustBlockCtx ctx = ZSTD_rust_block_context(dctx);
return ZSTD_rust_decompressBlock_internal(&ctx, dst, dstCapacity, src, srcSize,
(int)streaming);
}
void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize)
{
ZSTD_rustBlockCtx ctx = ZSTD_rust_block_context(dctx);
ZSTD_rust_checkContinuity(&ctx, dst, dstSize);
}
size_t ZSTD_decompressBlock_deprecated(ZSTD_DCtx* dctx,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize)
{
ZSTD_rustBlockCtx ctx = ZSTD_rust_block_context(dctx);
return ZSTD_rust_decompressBlock_deprecated(&ctx,
dst, dstCapacity, src, srcSize);
}
/* NOTE: Must just wrap ZSTD_decompressBlock_deprecated(). */
size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize)
{
return ZSTD_decompressBlock_deprecated(dctx, dst, dstCapacity, src, srcSize);
*out = ZSTD_rust_block_context(dctx);
}
+87
View File
@@ -30,6 +30,7 @@ use crate::huf_decompress::{
HUF_decompress1X_usingDTable, HUF_decompress4X_hufOnly_wksp, HUF_decompress4X_usingDTable,
};
use crate::mem::{MEM_32bits, MEM_64bits, MEM_readLE16, MEM_readLE24, U32};
use crate::zstd_decompress::ZSTD_DCtx;
use std::cmp::min;
use std::ffi::c_void;
use std::mem::MaybeUninit;
@@ -150,6 +151,17 @@ pub struct ZSTD_rustBlockCtx {
sequence_decoder_mode: c_int,
}
unsafe extern "C" {
fn ZSTD_rust_block_context_init(out: *mut ZSTD_rustBlockCtx, dctx: *mut ZSTD_DCtx);
}
#[inline]
unsafe fn block_context(dctx: *mut ZSTD_DCtx) -> ZSTD_rustBlockCtx {
let mut ctx = MaybeUninit::<ZSTD_rustBlockCtx>::uninit();
unsafe { ZSTD_rust_block_context_init(ctx.as_mut_ptr(), dctx) };
unsafe { ctx.assume_init() }
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct ZSTD_rustSeq {
@@ -1801,6 +1813,81 @@ pub unsafe extern "C" fn ZSTD_rust_decompressBlock_deprecated(
}
}
/* The public and hidden block-decoder entrypoints retain their C ABI, but the
* wrapper control flow lives here with the decoder implementation. C only
* projects the configuration-dependent private fields of ZSTD_DCtx. */
#[no_mangle]
pub unsafe extern "C" fn ZSTD_decodeLiteralsBlock_wrapper(
dctx: *mut ZSTD_DCtx,
src: *const c_void,
src_size: usize,
dst: *mut c_void,
dst_capacity: usize,
) -> usize {
let mut ctx = unsafe { block_context(dctx) };
unsafe { ZSTD_rust_decodeLiteralsBlock_wrapper(&mut ctx, src, src_size, dst, dst_capacity) }
}
#[no_mangle]
pub unsafe extern "C" fn ZSTD_decodeSeqHeaders(
dctx: *mut ZSTD_DCtx,
nb_seq_ptr: *mut c_int,
src: *const c_void,
src_size: usize,
) -> usize {
let mut ctx = unsafe { block_context(dctx) };
unsafe { ZSTD_rust_decodeSeqHeaders(&mut ctx, nb_seq_ptr, src, src_size) }
}
#[no_mangle]
pub unsafe extern "C" fn ZSTD_decompressBlock_internal(
dctx: *mut ZSTD_DCtx,
dst: *mut c_void,
dst_capacity: usize,
src: *const c_void,
src_size: usize,
streaming: c_int,
) -> usize {
let mut ctx = unsafe { block_context(dctx) };
unsafe {
ZSTD_rust_decompressBlock_internal(&mut ctx, dst, dst_capacity, src, src_size, streaming)
}
}
#[no_mangle]
pub unsafe extern "C" fn ZSTD_checkContinuity(
dctx: *mut ZSTD_DCtx,
dst: *const c_void,
dst_size: usize,
) {
let mut ctx = unsafe { block_context(dctx) };
unsafe { ZSTD_rust_checkContinuity(&mut ctx, dst, dst_size) };
}
#[no_mangle]
pub unsafe extern "C" fn ZSTD_decompressBlock_deprecated(
dctx: *mut ZSTD_DCtx,
dst: *mut c_void,
dst_capacity: usize,
src: *const c_void,
src_size: usize,
) -> usize {
let mut ctx = unsafe { block_context(dctx) };
unsafe { ZSTD_rust_decompressBlock_deprecated(&mut ctx, dst, dst_capacity, src, src_size) }
}
#[no_mangle]
pub unsafe extern "C" fn ZSTD_decompressBlock(
dctx: *mut ZSTD_DCtx,
dst: *mut c_void,
dst_capacity: usize,
src: *const c_void,
src_size: usize,
) -> usize {
unsafe { ZSTD_decompressBlock_deprecated(dctx, dst, dst_capacity, src, src_size) }
}
#[cfg(test)]
mod tests {
use super::*;