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
102 changes: 60 additions & 42 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,23 +363,25 @@ impl Generator {
};

let reply = {
let gen_zerocopy_decode = |repr_ty: &syn::Type, msg: &str| {
let reply_ty =
quote::format_ident!("{iface_name}_{name}_{msg}");
quote! {
let _len = len;
#[derive(
zerocopy_derive::TryFromBytes,
zerocopy_derive::Unaligned,
)]
#[repr(C, packed)]
struct #reply_ty {
value: #repr_ty,
}
let v: #repr_ty = zerocopy::TryFromBytes::try_read_from_bytes(&reply[..]).unwrap_lite();
}
};
let gen_decode = |t: &syntax::AttributedTy| match op.encoding {
syntax::Encoding::Zerocopy => {
let reply_ty =
quote::format_ident!("{iface_name}_{name}_REPLY");
let repr_ty = t.repr_ty();
quote! {
let _len = len;
#[derive(
zerocopy_derive::FromBytes,
zerocopy_derive::Unaligned,
)]
#[repr(C, packed)]
struct #reply_ty {
value: #repr_ty,
}
let v: #repr_ty = zerocopy::FromBytes::read_from_bytes(&reply[..]).unwrap_lite();
}
gen_zerocopy_decode(&t.repr_ty(), "REPLY")
}
syntax::Encoding::Ssmarshal => quote! {
let (v, _): (#t, _) = ssmarshal::deserialize(&reply[..len]).unwrap_lite();
Expand Down Expand Up @@ -483,43 +485,59 @@ impl Generator {
}
}
syntax::Error::Complex(ty) => {
let decode_v = match op.encoding {
syntax::Encoding::Hubpack => {
quote! {
let (v, _): (#ty, _) = hubpack::deserialize(&reply[..len]).unwrap_lite();
}
}
syntax::Encoding::Zerocopy
if ty.is_bool() =>
{
let decode = gen_zerocopy_decode(
&syn::parse_quote! { u8 },
"ERROR",
);
quote! {
#decode
let v = v != 0;
}
}
syntax::Encoding::Zerocopy => {
gen_zerocopy_decode(&ty.0, "ERROR")
}
e => {
panic!(
"Complex error types not supported for \
{e:?} encoding, sorry"
);
}
};
let count = match counters {
Some(ref ctrs) => {
ctrs.count_result(name, quote! {Err(v)})
}
None => quote! {},
};
match op.encoding {
syntax::Encoding::Hubpack => {
let check_server_death = if op
.idempotent
{
// Idempotent ops already checked for server death
// above.
quote! {}
} else {
quote! {
if let Some(g) = userlib::extract_new_generation(rc) {
self.current_id.set(userlib::TaskId::for_index_and_gen(task.index(), g));
let v = #ty::from(idol_runtime::ServerDeath);
#count
return Err(v);
}
}
};
quote! {
#check_server_death
let (v, _): (#ty, _) = hubpack::deserialize(&reply[..len]).unwrap_lite();
let check_server_death = if op.idempotent {
// Idempotent ops already checked for server death
// above.
quote! {}
} else {
quote! {
if let Some(g) = userlib::extract_new_generation(rc) {
self.current_id.set(userlib::TaskId::for_index_and_gen(task.index(), g));
let v = #ty::from(idol_runtime::ServerDeath);
#count
return Err(v);
}
}
e => {
panic!(
"Complex error types not supported for \
{e:?} encoding, sorry"
);
}
};
quote! {
#check_server_death
#decode_v
#count
return Err(v);
}
}
syntax::Error::ServerDeath => {
Expand Down
22 changes: 15 additions & 7 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -599,8 +599,19 @@ impl Generator {
//
// So, the fact that this error returns `Ok` is not a
// bug.
syntax::Error::Complex (ty) => match op.encoding {
syntax::Encoding::Hubpack => quote! {
syntax::Error::Complex (ty) => {
let reply = match op.encoding {
syntax::Encoding::Hubpack => quote! {
let mut reply_buf = [0u8; <#ty as hubpack::SerializedSize>::MAX_SIZE];
let n_reply = hubpack::serialize(&mut reply_buf, &e).map_err(|_| ()).unwrap_lite();
userlib::sys_reply(rm.sender, 1, &reply_buf[..n_reply]);
},
syntax::Encoding::Zerocopy => quote! {
userlib::sys_reply(rm.sender, 1, zerocopy::IntoBytes::as_bytes(&e));
},
encoding => panic!("Complex error types not supported for {encoding:?} encoding"),
};
quote! {
match val {
idol_runtime::RequestError::Fail(f) => {
// Note: because of the way `into_fault` works,
Expand All @@ -612,14 +623,11 @@ impl Generator {
}
}
idol_runtime::RequestError::Runtime(e) => {
let mut reply_buf = [0u8; <#ty as hubpack::SerializedSize>::MAX_SIZE];
let n_reply = hubpack::serialize(&mut reply_buf, &e).map_err(|_| ()).unwrap_lite();
userlib::sys_reply(rm.sender, 1, &reply_buf[..n_reply]);
#reply
}
}
Ok(())
},
encoding => panic!("Complex error types not supported for {encoding:?} encoding"),
}
},
syntax::Error::CLike(_) => quote! {
Err(val.map_runtime(u16::from))
Expand Down