refactor(decompress): move stack heap-mode policy to Rust
Move only the heap-mode branch decision for stack decompression into Rust while retaining the C-owned stack context, static initialization, error codes, and decoder projection. The Rust scalar policy preserves the historical heapmode >= 1 rejection boundary. Test Plan: - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings` -- passed - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/cli/Cargo.toml --all-targets -- -D warnings` -- passed - `ulimit -v 41943040; cargo +nightly fmt --manifest-path rust/Cargo.toml --all -- --check` -- passed - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 make -j1` -- passed - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 ./tests/rustLibSmoke` -- passed - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 make -j1 -C tests test` -- passed, including large streaming, native, fuzzer, and zstream phases
This commit is contained in:
@@ -138,6 +138,7 @@ void ZSTD_rust_dctx_init_platform(void* bmi2, int dynamic_bmi2);
|
||||
size_t ZSTD_rust_dctx_default_max_window_size(void);
|
||||
int ZSTD_rust_no_forward_progress_max(void);
|
||||
int ZSTD_rust_heapmode(void);
|
||||
int ZSTD_rust_decompress_stack_uses_heap(int heapmode);
|
||||
size_t ZSTD_rust_decompress_stack(void* dst, size_t dstCapacity,
|
||||
const void* src, size_t srcSize);
|
||||
size_t ZSTD_rust_decompress_stack_context(ZSTD_DCtx* dctx,
|
||||
@@ -274,19 +275,14 @@ int ZSTD_rust_heapmode(void)
|
||||
size_t ZSTD_rust_decompress_stack(void* dst, size_t dstCapacity,
|
||||
const void* src, size_t srcSize)
|
||||
{
|
||||
#if ZSTD_HEAPMODE >= 1
|
||||
(void)dst;
|
||||
(void)dstCapacity;
|
||||
(void)src;
|
||||
(void)srcSize;
|
||||
return ERROR(GENERIC);
|
||||
#else
|
||||
if (ZSTD_rust_decompress_stack_uses_heap(ZSTD_HEAPMODE)) {
|
||||
return ERROR(GENERIC);
|
||||
}
|
||||
ZSTD_DCtx dctx;
|
||||
ZSTD_DCtx* const initialized = ZSTD_initStaticDCtx(&dctx, sizeof(dctx));
|
||||
if (initialized == NULL) return ERROR(memory_allocation);
|
||||
return ZSTD_rust_decompress_stack_context(initialized, dst, dstCapacity,
|
||||
src, srcSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ZSTD_rust_dctx_trace_view(ZSTD_DCtx* dctx,
|
||||
|
||||
@@ -2913,6 +2913,16 @@ mod dctx_trace_tests {
|
||||
mod stack_context_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn stack_heapmode_policy_rejects_one_and_above_but_keeps_zero_and_negative() {
|
||||
for heapmode in [c_int::MIN, -1, 0] {
|
||||
assert_eq!(ZSTD_rust_decompress_stack_uses_heap(heapmode), 0);
|
||||
}
|
||||
for heapmode in [1, c_int::MAX] {
|
||||
assert_eq!(ZSTD_rust_decompress_stack_uses_heap(heapmode), 1);
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct StackDispatchProbe {
|
||||
static_size: usize,
|
||||
@@ -3625,6 +3635,20 @@ unsafe fn decompress_stack_context(
|
||||
unsafe { dispatch(view.dctx.cast(), dst, dst_capacity, src, src_size) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn decompress_stack_uses_heap(heapmode: c_int) -> bool {
|
||||
heapmode >= 1
|
||||
}
|
||||
|
||||
/// Select whether the C stack-decompression path must reject heap mode.
|
||||
///
|
||||
/// The C caller retains the stack context and static initialization; Rust
|
||||
/// owns only the configuration scalar's branch policy.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ZSTD_rust_decompress_stack_uses_heap(heapmode: c_int) -> c_int {
|
||||
c_int::from(decompress_stack_uses_heap(heapmode))
|
||||
}
|
||||
|
||||
/// Rust policy/dispatch for the C-owned stack context used by heapmode=0.
|
||||
///
|
||||
/// The context remains opaque here; the C projection supplies only the field
|
||||
|
||||
Reference in New Issue
Block a user