feat(decompress): invoke trace hooks from Rust
Keep weak-symbol discovery and private dctx/ddict extraction in the C adapter, but project the exact trace callback types into Rust and invoke them from the Rust trace lifecycle. Preserve the nullable-hook behavior, trace context width, dictionary-cold timing, record field layout, size conversions, and the no-trace build path. Add focused Rust policy tests for callback, record, and null-projection behavior. Test Plan: - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo check --manifest-path rust/Cargo.toml --tests - ulimit -v 41943040; make -j1 - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/cli/Cargo.toml --all-targets -- -D warnings - ulimit -v 41943040; make -j1 -C tests test
This commit is contained in:
@@ -116,15 +116,21 @@ typedef char ZSTD_rust_dctx_view_layout[
|
|||||||
* representation instead of U64, whose typedef may be a different C type on
|
* representation instead of U64, whose typedef may be a different C type on
|
||||||
* some targets even when it has the same width. */
|
* some targets even when it has the same width. */
|
||||||
typedef unsigned long long ZSTD_rustTraceCtx;
|
typedef unsigned long long ZSTD_rustTraceCtx;
|
||||||
|
#if ZSTD_TRACE
|
||||||
|
typedef ZSTD_rustTraceCtx (*ZSTD_rustTraceBeginFn)(const ZSTD_DCtx* dctx);
|
||||||
|
typedef void (*ZSTD_rustTraceEndFn)(ZSTD_rustTraceCtx traceCtx,
|
||||||
|
const ZSTD_Trace* trace);
|
||||||
|
#else
|
||||||
typedef ZSTD_rustTraceCtx (*ZSTD_rustTraceBeginFn)(const void* dctx);
|
typedef ZSTD_rustTraceCtx (*ZSTD_rustTraceBeginFn)(const void* dctx);
|
||||||
typedef void (*ZSTD_rustTraceEndFn)(ZSTD_rustTraceCtx traceCtx,
|
typedef void (*ZSTD_rustTraceEndFn)(ZSTD_rustTraceCtx traceCtx,
|
||||||
const void* trace);
|
const void* trace);
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ZSTD_rustTraceCtx* trace_ctx;
|
ZSTD_rustTraceCtx* trace_ctx;
|
||||||
ZSTD_rustTraceBeginFn begin;
|
ZSTD_rustTraceBeginFn begin;
|
||||||
ZSTD_rustTraceEndFn end;
|
ZSTD_rustTraceEndFn end;
|
||||||
const void* dctx;
|
const ZSTD_DCtx* dctx;
|
||||||
const void* ddict;
|
const void* ddict;
|
||||||
int dictionary_is_cold;
|
int dictionary_is_cold;
|
||||||
} ZSTD_rustDctxTraceView;
|
} ZSTD_rustDctxTraceView;
|
||||||
@@ -226,23 +232,6 @@ unsigned ZSTD_rust_legacy_support_policy(
|
|||||||
const ZSTD_rustLegacySupportProjection* projection);
|
const ZSTD_rustLegacySupportProjection* projection);
|
||||||
unsigned ZSTD_rust_legacy_support(void);
|
unsigned ZSTD_rust_legacy_support(void);
|
||||||
|
|
||||||
#if ZSTD_TRACE
|
|
||||||
static ZSTD_rustTraceCtx ZSTD_rust_trace_begin_callback(const void* dctx)
|
|
||||||
{
|
|
||||||
return (ZSTD_trace_decompress_begin != NULL)
|
|
||||||
? ZSTD_trace_decompress_begin((const ZSTD_DCtx*)dctx) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ZSTD_rust_trace_end_callback(ZSTD_rustTraceCtx traceCtx,
|
|
||||||
const void* trace)
|
|
||||||
{
|
|
||||||
if (ZSTD_trace_decompress_end != NULL) {
|
|
||||||
ZSTD_trace_decompress_end((ZSTD_TraceCtx)traceCtx,
|
|
||||||
(const ZSTD_Trace*)trace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void ZSTD_rust_dctx_view(ZSTD_DCtx* dctx, ZSTD_rustDctxView* out)
|
void ZSTD_rust_dctx_view(ZSTD_DCtx* dctx, ZSTD_rustDctxView* out)
|
||||||
{
|
{
|
||||||
ZSTD_memset(out, 0, sizeof(*out));
|
ZSTD_memset(out, 0, sizeof(*out));
|
||||||
@@ -389,9 +378,9 @@ void ZSTD_rust_dctx_trace_view(ZSTD_DCtx* dctx,
|
|||||||
#if ZSTD_TRACE
|
#if ZSTD_TRACE
|
||||||
out->trace_ctx = &dctx->traceCtx;
|
out->trace_ctx = &dctx->traceCtx;
|
||||||
out->begin = (ZSTD_trace_decompress_begin != NULL)
|
out->begin = (ZSTD_trace_decompress_begin != NULL)
|
||||||
? ZSTD_rust_trace_begin_callback : NULL;
|
? ZSTD_trace_decompress_begin : NULL;
|
||||||
out->end = (ZSTD_trace_decompress_end != NULL)
|
out->end = (ZSTD_trace_decompress_end != NULL)
|
||||||
? ZSTD_rust_trace_end_callback : NULL;
|
? ZSTD_trace_decompress_end : NULL;
|
||||||
out->ddict = dctx->ddict;
|
out->ddict = dctx->ddict;
|
||||||
out->dictionary_is_cold = dctx->ddictIsCold;
|
out->dictionary_is_cold = dctx->ddictIsCold;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -358,8 +358,8 @@ const _: () = {
|
|||||||
assert!(align_of::<ZSTD_rustDctxView>() == align_of::<usize>());
|
assert!(align_of::<ZSTD_rustDctxView>() == align_of::<usize>());
|
||||||
};
|
};
|
||||||
|
|
||||||
type ZSTD_rustTraceBeginFn = unsafe extern "C" fn(*const c_void) -> u64;
|
type ZSTD_rustTraceBeginFn = unsafe extern "C" fn(*const ZSTD_DCtx) -> u64;
|
||||||
type ZSTD_rustTraceEndFn = unsafe extern "C" fn(u64, *const c_void);
|
type ZSTD_rustTraceEndFn = unsafe extern "C" fn(u64, *const ZSTD_rustTrace);
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
@@ -367,7 +367,7 @@ struct ZSTD_rustDctxTraceView {
|
|||||||
trace_ctx: *mut u64,
|
trace_ctx: *mut u64,
|
||||||
begin: Option<ZSTD_rustTraceBeginFn>,
|
begin: Option<ZSTD_rustTraceBeginFn>,
|
||||||
end: Option<ZSTD_rustTraceEndFn>,
|
end: Option<ZSTD_rustTraceEndFn>,
|
||||||
dctx: *const c_void,
|
dctx: *const ZSTD_DCtx,
|
||||||
ddict: *const c_void,
|
ddict: *const c_void,
|
||||||
dictionary_is_cold: c_int,
|
dictionary_is_cold: c_int,
|
||||||
}
|
}
|
||||||
@@ -386,6 +386,44 @@ struct ZSTD_rustTrace {
|
|||||||
dctx: *const c_void,
|
dctx: *const c_void,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const _: () = {
|
||||||
|
assert!(offset_of!(ZSTD_rustTrace, version) == 0);
|
||||||
|
assert!(offset_of!(ZSTD_rustTrace, streaming) == size_of::<c_uint>());
|
||||||
|
assert!(offset_of!(ZSTD_rustTrace, dictionary_id) == size_of::<c_uint>() + size_of::<c_int>());
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rustTrace, dictionary_is_cold)
|
||||||
|
== 2 * size_of::<c_uint>() + size_of::<c_int>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rustTrace, dictionary_size)
|
||||||
|
== 2 * size_of::<c_uint>() + 2 * size_of::<c_int>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rustTrace, uncompressed_size)
|
||||||
|
== offset_of!(ZSTD_rustTrace, dictionary_size) + size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rustTrace, compressed_size)
|
||||||
|
== offset_of!(ZSTD_rustTrace, dictionary_size) + 2 * size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rustTrace, params)
|
||||||
|
== offset_of!(ZSTD_rustTrace, dictionary_size) + 3 * size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rustTrace, cctx)
|
||||||
|
== offset_of!(ZSTD_rustTrace, dictionary_size) + 4 * size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rustTrace, dctx)
|
||||||
|
== offset_of!(ZSTD_rustTrace, dictionary_size) + 5 * size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
size_of::<ZSTD_rustTrace>()
|
||||||
|
== offset_of!(ZSTD_rustTrace, dictionary_size) + 6 * size_of::<usize>()
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
/* Keep this in sync with ZSTD_VERSION_NUMBER in lib/zstd.h. */
|
/* Keep this in sync with ZSTD_VERSION_NUMBER in lib/zstd.h. */
|
||||||
const ZSTD_TRACE_VERSION: c_uint = 10_507;
|
const ZSTD_TRACE_VERSION: c_uint = 10_507;
|
||||||
|
|
||||||
@@ -579,7 +617,7 @@ unsafe fn trace_end_with_view(
|
|||||||
compressed_size: compressed_size as usize,
|
compressed_size: compressed_size as usize,
|
||||||
params: ptr::null(),
|
params: ptr::null(),
|
||||||
cctx: ptr::null(),
|
cctx: ptr::null(),
|
||||||
dctx: view.dctx,
|
dctx: view.dctx.cast(),
|
||||||
};
|
};
|
||||||
if !view.ddict.is_null() {
|
if !view.ddict.is_null() {
|
||||||
let ddict = view.ddict.cast::<ZSTD_DDict>();
|
let ddict = view.ddict.cast::<ZSTD_DDict>();
|
||||||
@@ -587,7 +625,7 @@ unsafe fn trace_end_with_view(
|
|||||||
trace.dictionary_size = unsafe { ZSTD_DDict_dictSize(ddict) };
|
trace.dictionary_size = unsafe { ZSTD_DDict_dictSize(ddict) };
|
||||||
trace.dictionary_is_cold = view.dictionary_is_cold;
|
trace.dictionary_is_cold = view.dictionary_is_cold;
|
||||||
}
|
}
|
||||||
unsafe { end(trace_ctx, (&mut trace as *mut ZSTD_rustTrace).cast()) };
|
unsafe { end(trace_ctx, ptr::addr_of!(trace)) };
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn trace_begin(dctx: *mut ZSTD_DCtx) {
|
unsafe fn trace_begin(dctx: *mut ZSTD_DCtx) {
|
||||||
@@ -3053,7 +3091,7 @@ mod dctx_trace_tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn trace_begin_probe(dctx: *const c_void) -> u64 {
|
unsafe extern "C" fn trace_begin_probe(dctx: *const ZSTD_DCtx) -> u64 {
|
||||||
let probe = dctx.cast::<TraceProbe>();
|
let probe = dctx.cast::<TraceProbe>();
|
||||||
if probe.is_null() {
|
if probe.is_null() {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -3064,11 +3102,11 @@ mod dctx_trace_tests {
|
|||||||
0xD1CE
|
0xD1CE
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn trace_end_probe(trace_ctx: u64, trace_ptr: *const c_void) {
|
unsafe extern "C" fn trace_end_probe(trace_ctx: u64, trace_ptr: *const ZSTD_rustTrace) {
|
||||||
if trace_ptr.is_null() {
|
if trace_ptr.is_null() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let trace = unsafe { &*trace_ptr.cast::<ZSTD_rustTrace>() };
|
let trace = unsafe { &*trace_ptr };
|
||||||
let probe = trace.dctx.cast::<TraceProbe>();
|
let probe = trace.dctx.cast::<TraceProbe>();
|
||||||
if probe.is_null() {
|
if probe.is_null() {
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user