From 440585995bdb78d32ba44a628b5cf98de7f13352 Mon Sep 17 00:00:00 2001 From: ddidderr Date: Sat, 18 Jul 2026 23:46:08 +0200 Subject: [PATCH] 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 --- lib/decompress/zstd_decompress_block.c | 74 +++------------------- rust/src/zstd_decompress_block.rs | 87 ++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 67 deletions(-) diff --git a/lib/decompress/zstd_decompress_block.c b/lib/decompress/zstd_decompress_block.c index 81dfdbfaa..1fd9f89bc 100644 --- a/lib/decompress/zstd_decompress_block.c +++ b/lib/decompress/zstd_decompress_block.c @@ -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); } diff --git a/rust/src/zstd_decompress_block.rs b/rust/src/zstd_decompress_block.rs index 0f2e07603..fe15aa060 100644 --- a/rust/src/zstd_decompress_block.rs +++ b/rust/src/zstd_decompress_block.rs @@ -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::::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::*;