refactor(decompress): move no-progress threshold policy to Rust
ZSTD_NO_FORWARD_PROGRESS_MAX is a compile-time override that was returned directly by the C adapter. Keep the active build value in C, where configuration belongs, but pass it through an ABI-checked scalar projection to Rust. Rust now owns the policy boundary and preserves the exact configured threshold, while the existing stalled-stream comparison, error mapping, and private DCtx layout remain unchanged. Test Plan: - `git diff --cached --check` -- passed - Cargo, make, builds, native tests, and heavy verification were not run per request.
This commit is contained in:
@@ -187,6 +187,15 @@ typedef char ZSTD_rust_decompress_stack_callbacks_layout[
|
|||||||
size_t ZSTD_rust_decompress_stack_action(
|
size_t ZSTD_rust_decompress_stack_action(
|
||||||
const ZSTD_rustDecompressStackProjection* projection,
|
const ZSTD_rustDecompressStackProjection* projection,
|
||||||
const ZSTD_rustDecompressStackCallbacks* callbacks);
|
const ZSTD_rustDecompressStackCallbacks* callbacks);
|
||||||
|
typedef struct {
|
||||||
|
int configured_max;
|
||||||
|
} ZSTD_rustNoForwardProgressProjection;
|
||||||
|
typedef char ZSTD_rust_no_forward_progress_projection_layout[
|
||||||
|
(offsetof(ZSTD_rustNoForwardProgressProjection, configured_max) == 0
|
||||||
|
&& sizeof(ZSTD_rustNoForwardProgressProjection) == sizeof(int))
|
||||||
|
? 1 : -1];
|
||||||
|
int ZSTD_rust_no_forward_progress_policy(
|
||||||
|
const ZSTD_rustNoForwardProgressProjection* projection);
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned configured_level;
|
unsigned configured_level;
|
||||||
} ZSTD_rustLegacySupportProjection;
|
} ZSTD_rustLegacySupportProjection;
|
||||||
@@ -316,7 +325,10 @@ size_t ZSTD_rust_dctx_default_max_window_size(void)
|
|||||||
|
|
||||||
int ZSTD_rust_no_forward_progress_max(void)
|
int ZSTD_rust_no_forward_progress_max(void)
|
||||||
{
|
{
|
||||||
return ZSTD_NO_FORWARD_PROGRESS_MAX;
|
ZSTD_rustNoForwardProgressProjection const projection = {
|
||||||
|
ZSTD_NO_FORWARD_PROGRESS_MAX
|
||||||
|
};
|
||||||
|
return ZSTD_rust_no_forward_progress_policy(&projection);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ZSTD_rust_heapmode(void)
|
int ZSTD_rust_heapmode(void)
|
||||||
|
|||||||
@@ -310,6 +310,17 @@ const _: () = {
|
|||||||
assert!(size_of::<ZSTD_rustLegacySupportProjection>() == size_of::<c_uint>());
|
assert!(size_of::<ZSTD_rustLegacySupportProjection>() == size_of::<c_uint>());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||||
|
pub struct ZSTD_rustNoForwardProgressProjection {
|
||||||
|
pub configured_max: c_int,
|
||||||
|
}
|
||||||
|
|
||||||
|
const _: () = {
|
||||||
|
assert!(offset_of!(ZSTD_rustNoForwardProgressProjection, configured_max) == 0);
|
||||||
|
assert!(size_of::<ZSTD_rustNoForwardProgressProjection>() == size_of::<c_int>());
|
||||||
|
};
|
||||||
|
|
||||||
const _: () = {
|
const _: () = {
|
||||||
assert!(offset_of!(ZSTD_rustDctxView, dctx) == 0);
|
assert!(offset_of!(ZSTD_rustDctxView, dctx) == 0);
|
||||||
assert!(offset_of!(ZSTD_rustDctxView, static_size) == 29 * size_of::<usize>());
|
assert!(offset_of!(ZSTD_rustDctxView, static_size) == 29 * size_of::<usize>());
|
||||||
@@ -656,6 +667,45 @@ unsafe fn configured_legacy_support() -> u32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Preserve the active C build's no-forward-progress threshold.
|
||||||
|
///
|
||||||
|
/// C supplies the compile-time value because it may be overridden by the
|
||||||
|
/// build. Rust owns the scalar policy boundary without baking a second
|
||||||
|
/// default into the decoder.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn ZSTD_rust_no_forward_progress_policy(
|
||||||
|
projection: *const ZSTD_rustNoForwardProgressProjection,
|
||||||
|
) -> c_int {
|
||||||
|
let Some(projection) = (unsafe { projection.as_ref() }) else {
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
projection.configured_max
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod no_forward_progress_policy_tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn preserves_the_configured_threshold() {
|
||||||
|
for configured_max in [c_int::MIN, -1, 0, 1, 16, c_int::MAX] {
|
||||||
|
let projection = ZSTD_rustNoForwardProgressProjection { configured_max };
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { ZSTD_rust_no_forward_progress_policy(&projection) },
|
||||||
|
configured_max
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rejects_missing_configuration_projection() {
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { ZSTD_rust_no_forward_progress_policy(ptr::null()) },
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Normalize the C build's legacy-support threshold before dispatch.
|
/// Normalize the C build's legacy-support threshold before dispatch.
|
||||||
///
|
///
|
||||||
/// C supplies the active compile-time value because test builds intentionally
|
/// C supplies the active compile-time value because test builds intentionally
|
||||||
|
|||||||
Reference in New Issue
Block a user