use fuel_cpu_backend::byte_storage::CpuStorageBytes;
use fuel_ir::storage::{OutputViewSpec, compose_bundle};
use fuel_ir::{DType, Shape};
use fuel_memory::{BackendStorage, Storage};
use std::sync::Arc;
enum Outcome {
Err(String),
Panic(String),
Ok {
slots: usize,
},
}
impl std::fmt::Debug for Outcome {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Outcome::Err(s) => write!(f, "Err({s:?})"),
Outcome::Panic(s) => write!(f, "Panic({s:?})"),
Outcome::Ok { slots } => write!(f, "Ok {{ slots: {slots:?} }}"),
}
}
}
fn specs_of(n: usize) -> Vec<OutputViewSpec> {
(0..n)
.map(|i| OutputViewSpec::contiguous(DType::F32, Shape::from_dims(&[4 + i])))
.collect()
}
fn bundled(n: usize) -> Storage {
let (total_bytes, views) = compose_bundle(&specs_of(n)).expect("compose_bundle");
Storage::new_bundled(
BackendStorage::Cpu(CpuStorageBytes::from_zero_bytes(total_bytes)),
DType::F32,
Arc::from(views.into_boxed_slice()),
)
.expect("new_bundled")
}
fn bundle_of(n: usize) -> Arc<[fuel_ir::storage::OutputView]> {
let (_bytes, views) = compose_bundle(&specs_of(n)).expect("compose_bundle");
Arc::from(views.into_boxed_slice())
}
fn probe<F: FnOnce() -> fuel_ir::Result<Storage> + std::panic::UnwindSafe>(f: F) -> Outcome {
let prev = std::panic::take_hook();
std::panic::set_hook(Box::new(|_| {}));
let r = std::panic::catch_unwind(f);
std::panic::set_hook(prev);
match r {
Err(p) => {
let msg = p
.downcast_ref::<String>()
.cloned()
.or_else(|| p.downcast_ref::<&str>().map(|s| (*s).to_string()))
.unwrap_or_else(|| "<non-string panic>".into());
Outcome::Panic(msg.lines().next().unwrap_or("").to_string())
}
Ok(Err(e)) => Outcome::Err(format!("{e}").lines().next().unwrap_or("").to_string()),
Ok(Ok(s)) => Outcome::Ok {
slots: s.bundle().map(|b| b.len()).unwrap_or(0),
},
}
}
fn main() {
println!(
"\n=== GAP-315 (d)-SIDE FORWARD TEST: Storage::with_bundle ===\n\
debug_assertions = {} ({})",
cfg!(debug_assertions),
if cfg!(debug_assertions) {
"ARM A - guard PRESENT (positive control)"
} else {
"ARM B - guard ABSENT (what the shipped artifact does)"
}
);
println!(
" [control] unbundled + with_bundle(2) -> {:?}",
probe(|| {
let s = Storage::new(
BackendStorage::Cpu(CpuStorageBytes::from_zero_bytes(64)),
DType::F32,
);
s.with_bundle(bundle_of(2))
})
);
println!(
" [ctl-err] unbundled + EMPTY bundle -> {:?}",
probe(|| {
let s = Storage::new(
BackendStorage::Cpu(CpuStorageBytes::from_zero_bytes(64)),
DType::F32,
);
s.with_bundle(Arc::from(Vec::new().into_boxed_slice()))
})
);
println!(
" [rebundle] bundled(3) + with_bundle(2) -> {:?}",
probe(|| bundled(3).with_bundle(bundle_of(2)))
);
println!(
" [rebundle2] bundled(2) + with_bundle(5) -> {:?}",
probe(|| bundled(2).with_bundle(bundle_of(5)))
);
println!(" (measurement only - asserts nothing)");
}