Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmd/host/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,9 @@ fn read_qualified_state_buf(
return Ok(None);
};

let as_static_cell: doppel::ClaimOnceCell =
let as_static_cell: doppel::ClaimOnceCell<HostStateBuf> =
reflect::read_variable(hubris, core, var)?;
Ok(Some(HostStateBuf::from_value(&as_static_cell.cell.value)?))
Ok(Some(as_static_cell.cell.value))
}

fn print_escaped_ascii(mut bytes: &[u8]) {
Expand Down
6 changes: 3 additions & 3 deletions cmd/ringbuf/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,9 @@ fn ringbuf_dump(
Ringbuf::from_value(&ringbuf_val).map(|r| (Some(r), None))
})
.or_else(|_e| {
let cell: StaticCell = StaticCell::from_value(&ringbuf_val)?;
let ringbuf = Ringbuf::from_value(&cell.cell.value)?;
Ok::<_, anyhow::Error>((Some(ringbuf), None))
let cell: StaticCell<Ringbuf> =
StaticCell::from_value(&ringbuf_val)?;
Ok::<_, anyhow::Error>((Some(cell.cell.value), None))
})?;

if let (Some(mut counters), false) = (counters, no_totals) {
Expand Down
41 changes: 11 additions & 30 deletions humility-doppel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,38 +387,23 @@ pub enum CounterVariant {
}

#[derive(Clone, Debug, Load)]
pub struct ClaimOnceCell {
pub cell: UnsafeCell,
pub struct ClaimOnceCell<T: Load> {
pub cell: UnsafeCell<T>,
}

#[derive(Clone, Debug, Load)]
pub struct StaticCell {
pub cell: UnsafeCell,
pub struct StaticCell<T: Load> {
pub cell: UnsafeCell<T>,
}

#[derive(Clone, Debug, Load)]
pub struct UnsafeCell {
pub value: Value,
}

#[derive(Clone, Debug)]
pub struct MaybeUninit<T> {
pub struct UnsafeCell<T: Load> {
pub value: T,
}

impl<T: humility::reflect::Load> humility::reflect::Load for MaybeUninit<T> {
fn from_value(v: &Value) -> Result<Self> {
let v_struct = v.as_struct()?;
anyhow::ensure!(
v_struct.name().starts_with("MaybeUninit"),
"expected MaybeUninit, got {:?}",
v_struct.name()
);
let value = v_struct
.get("value")
.ok_or_else(|| anyhow!("missing `value` member"))?;
T::from_value(value).map(|value| Self { value })
}
#[derive(Clone, Debug, Load)]
pub struct MaybeUninit<T: Load> {
pub value: T,
}

/// Double of the struct from `udprpc`
Expand Down Expand Up @@ -571,13 +556,9 @@ impl humility::reflect::Load for CounterVariant {

let counter = value.as_struct()?;
if counter.name().starts_with("AtomicU32") {
let cell = UnsafeCell::from_value(&counter["v"])?;
return cell
.value
.as_base()?
.as_u32()
.map(Self::Single)
.ok_or_else(|| anyhow::anyhow!("ringbuf count must be a u32"));
let cell = UnsafeCell::<u32>::from_value(&counter["v"])
.context("ringbuf count must be a u32")?;
return Ok(Self::Single(cell.value));
}

Ok(Self::Nested(Counters::from_value(value)?))
Expand Down
19 changes: 6 additions & 13 deletions humility-spd/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use humility::hubris::*;
use humility::{
reflect,
reflect::{Base, Load, Value},
reflect::{Base, Value},
};
use humility_doppel as doppel;

Expand Down Expand Up @@ -66,18 +66,11 @@ pub fn spd_lookup(
.collect(),
))
} else if let Ok(var) = hubris.lookup_qualified_variable(PACKRAT_BUF_NAME) {
let var_ty = hubris.lookup_type(var.goff)?;
let mut buf: Vec<u8> = vec![0u8; var.size];

core.halt()?;
core.read_8(var.addr, &mut buf)?;
core.run()?;

let v = reflect::load_value(hubris, &buf, var_ty, 0)?;
let as_static_cell = doppel::ClaimOnceCell::from_value(&v)?;
let Value::Struct(packrat_bufs) = &as_static_cell.cell.value else {
bail!("expected {PACKRAT_BUF_NAME} to be a struct");
};
let packrat_bufs = reflect::read_variable::<
doppel::ClaimOnceCell<reflect::Struct>,
>(hubris, core, var)?
.cell
.value;
let Some(Value::Struct(compute_sled_bufs)) = packrat_bufs
.get("gimlet_bufs")
.or_else(|| packrat_bufs.get("cosmo_bufs"))
Expand Down
64 changes: 60 additions & 4 deletions load_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ pub fn load_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let ts = match &input.data {
syn::Data::Struct(data) => match &data.fields {
syn::Fields::Named(fields) => {
gen_named_struct(&input.ident, fields)
gen_named_struct(&input.ident, &input.generics, fields)
}
syn::Fields::Unnamed(fields) => {
gen_unnamed_struct(&input.ident, fields)
gen_unnamed_struct(&input.ident, &input.generics, fields)
}
syn::Fields::Unit => {
unimplemented!(
Expand All @@ -31,6 +31,56 @@ pub fn load_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
proc_macro::TokenStream::from(ts)
}

/// Returns generics to go by the `impl` keyword (e.g. `<T: Load>`)
fn impl_generics(g: &syn::Generics) -> Option<proc_macro2::TokenStream> {
if g.lt_token.is_some() {
let iter = g
.params
.iter()
.flat_map(|p| {
if let syn::GenericParam::Type(t) = p {
let mut t = t.clone();
t.attrs.clear();
t.eq_token = None;
t.default = None;
Some(quote_spanned!(p.span()=>#t))
} else {
None
}
})
.collect::<Vec<_>>();
Some(quote_spanned!(g.span()=><#(#iter),*>))
} else {
None
}
}

/// Returns generics to go by the `struct` keyword (e.g. `<T>`)
fn struct_generics(g: &syn::Generics) -> Option<proc_macro2::TokenStream> {
if g.lt_token.is_some() {
let iter = g
.params
.iter()
.flat_map(|p| {
if let syn::GenericParam::Type(t) = p {
let mut t = t.clone();
t.attrs.clear();
t.colon_token = None;
t.bounds.clear();
t.eq_token = None;
t.default = None;
Some(quote_spanned!(p.span()=>#t))
} else {
None
}
})
.collect::<Vec<_>>();
Some(quote_spanned!(g.span()=><#(#iter),*>))
} else {
None
}
}

fn gen_enum(
ident: &syn::Ident,
data: &syn::DataEnum,
Expand Down Expand Up @@ -128,6 +178,7 @@ fn gen_enum(

fn gen_named_struct(
ident: &syn::Ident,
generics: &syn::Generics,
fields: &syn::FieldsNamed,
) -> proc_macro2::TokenStream {
let field_name_strs = fields.named.iter().map(|fld| {
Expand All @@ -144,8 +195,10 @@ fn gen_named_struct(
});
let field_defs = field_defs.collect::<proc_macro2::TokenStream>();

let impl_generics = impl_generics(generics);
let struct_generics = struct_generics(generics);
quote_spanned!(ident.span()=>
impl humility::reflect::Load for #ident {
impl #impl_generics humility::reflect::Load for #ident #struct_generics {
fn from_value(v: &humility::reflect::Value) -> anyhow::Result<Self> {
let v = v.as_struct()?;
v.check_members(&[#field_name_strs])?;
Expand All @@ -159,6 +212,7 @@ fn gen_named_struct(

fn gen_unnamed_struct(
ident: &syn::Ident,
generics: &syn::Generics,
fields: &syn::FieldsUnnamed,
) -> proc_macro2::TokenStream {
let len = fields.unnamed.len();
Expand All @@ -177,8 +231,10 @@ fn gen_unnamed_struct(
});
let field_uses = field_uses.collect::<proc_macro2::TokenStream>();

let impl_generics = impl_generics(generics);
let struct_generics = struct_generics(generics);
quote_spanned!(ident.span()=>
impl humility::reflect::Load for #ident {
impl #impl_generics humility::reflect::Load for #ident #struct_generics {
fn from_value(v: &humility::reflect::Value) -> anyhow::Result<Self> {
let v = v.as_tuple()?;
if v.len() != #len {
Expand Down
Loading