Sitelet https://github.com/alloy-rs/core/pull/1167/files
Skip to content
24 changes: 14 additions & 10 deletions crates/dyn-abi/src/dynamic/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,17 +139,20 @@ impl<'a> DynToken<'a> {

/// Decodes from a decoder, populating the structure with the decoded data.
#[inline]
pub(crate) fn decode_populate(&mut self, dec: &mut Decoder<'a>) -> Result<()> {
pub(crate) fn decode_populate(&mut self, dec: &mut Decoder<'a, '_>) -> Result<()> {
match self {
Self::Word(w) => *w = WordToken::decode_from(dec)?.0,
Self::FixedSeq(..) => {
let dynamic = self.is_dynamic();
let mut child = if dynamic { dec.take_indirection() } else { dec.raw_child() }?;

self.decode_sequence_populate(&mut child)?;

if !dynamic {
dec.take_offset_from(&child);
if self.is_dynamic() {
let mut child = dec.take_indirection()?;
self.decode_sequence_populate(&mut child)?;
} else {
let offset = {
let mut child = dec.raw_child()?;
self.decode_sequence_populate(&mut child)?;
dec.offset_from_child(&child)
};
dec.set_offset(offset);
}
}
Self::DynSeq { contents, template } => {
Expand Down Expand Up @@ -189,6 +192,7 @@ impl<'a> DynToken<'a> {
// re-use the box allocation
unsafe { Vec::from_raw_parts(Box::into_raw(template), 1, 1) }
} else {
child.reserve_elements::<Self>(size)?;
try_vec![*template; size]?
};

Expand All @@ -206,7 +210,7 @@ impl<'a> DynToken<'a> {
/// Decode a sequence from the decoder, populating the data by consuming
/// decoder words.
#[inline]
pub(crate) fn decode_sequence_populate(&mut self, dec: &mut Decoder<'a>) -> Result<()> {
pub(crate) fn decode_sequence_populate(&mut self, dec: &mut Decoder<'a, '_>) -> Result<()> {
match self {
Self::FixedSeq(buf, size) => {
buf.to_mut().iter_mut().take(*size).try_for_each(|item| item.decode_populate(dec))
Expand All @@ -218,7 +222,7 @@ impl<'a> DynToken<'a> {

/// Decode a single item of this type, as a sequence of length 1.
#[inline]
pub(crate) fn decode_single_populate(&mut self, dec: &mut Decoder<'a>) -> Result<()> {
pub(crate) fn decode_single_populate(&mut self, dec: &mut Decoder<'a, '_>) -> Result<()> {
// This is what
// `Self::FixedSeq(vec![self.clone()], 1).decode_populate()`
// would do, so we skip the allocation.
Expand Down
4 changes: 2 additions & 2 deletions crates/dyn-abi/src/dynamic/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,11 +602,11 @@ impl DynSolType {
#[cfg_attr(debug_assertions, track_caller)]
pub(crate) fn abi_decode_inner<'d, F>(
&self,
decoder: &mut Decoder<'d>,
decoder: &mut Decoder<'d, '_>,
f: F,
) -> Result<DynSolValue>
where
F: FnOnce(&mut DynToken<'d>, &mut Decoder<'d>) -> Result<()>,
F: FnOnce(&mut DynToken<'d>, &mut Decoder<'d, '_>) -> Result<()>,
{
if self.is_zst() {
return Ok(self.zero_sized_value().expect("checked"));
Expand Down
58 changes: 35 additions & 23 deletions crates/sol-macro-expander/src/expand/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -757,11 +757,34 @@ impl CallLikeExpander<'_> {
selector: [u8; 4],
data: &[u8],
)-> alloy_sol_types::Result<Self> {
static DECODE_SHIMS: &[fn(&[u8]) -> alloy_sol_types::Result<#name>] = &[
Self::abi_decode_raw_with_config(
selector,
data,
alloy_sol_types::abi::AbiDecoderConfig::default(),
)
}

#[inline]
#[allow(non_snake_case)]
fn abi_decode_raw_with_config(
selector: [u8; 4],
data: &[u8],
config: alloy_sol_types::abi::AbiDecoderConfig,
) -> alloy_sol_types::Result<Self> {
static DECODE_SHIMS: &[fn(
&[u8],
alloy_sol_types::abi::AbiDecoderConfig,
) -> alloy_sol_types::Result<#name>] = &[
#({
fn #sorted_variants(data: &[u8]) -> alloy_sol_types::Result<#name> {
<#sorted_types as alloy_sol_types::#trait_>::abi_decode_raw(data)
.map(#name::#sorted_variants)
fn #sorted_variants(
data: &[u8],
config: alloy_sol_types::abi::AbiDecoderConfig,
) -> alloy_sol_types::Result<#name> {
<#sorted_types as alloy_sol_types::#trait_>::abi_decode_raw_with_config(
data,
config,
)
.map(#name::#sorted_variants)
}
#sorted_variants
}),*
Expand All @@ -774,33 +797,22 @@ impl CallLikeExpander<'_> {
));
};
// `SELECTORS` and `DECODE_SHIMS` have the same length and are sorted in the same order.
DECODE_SHIMS[idx](data)
DECODE_SHIMS[idx](data, config)
}

#[inline]
#[allow(non_snake_case)]
// TODO: Deprecate in favor of a validating decoder configuration.
// #[deprecated(note = "use a validating decoder configuration")]
fn abi_decode_raw_validate(
selector: [u8; 4],
data: &[u8],
) -> alloy_sol_types::Result<Self> {
static DECODE_VALIDATE_SHIMS: &[fn(&[u8]) -> alloy_sol_types::Result<#name>] = &[
#({
fn #sorted_variants(data: &[u8]) -> alloy_sol_types::Result<#name> {
<#sorted_types as alloy_sol_types::#trait_>::abi_decode_raw_validate(data)
.map(#name::#sorted_variants)
}
#sorted_variants
}),*
];

let Ok(idx) = Self::SELECTORS.binary_search(&selector) else {
return Err(alloy_sol_types::Error::unknown_selector(
<Self as alloy_sol_types::SolInterface>::NAME,
selector,
));
};
// `SELECTORS` and `DECODE_VALIDATE_SHIMS` have the same length and are sorted in the same order.
DECODE_VALIDATE_SHIMS[idx](data)
Self::abi_decode_raw_with_config(
selector,
data,
alloy_sol_types::abi::AbiDecoderConfig::new().validate(true),
)
}

#[inline]
Expand Down
7 changes: 6 additions & 1 deletion crates/sol-macro-expander/src/expand/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,13 @@ pub(super) fn expand(cx: &ExpCtxt<'_>, error: &ItemError) -> Result<TokenStream>
}

#[inline]
// TODO: Deprecate in favor of a validating decoder configuration.
// #[deprecated(note = "use a validating decoder configuration")]
fn abi_decode_raw_validate(data: &[u8]) -> alloy_sol_types::Result<Self> {
<Self::Parameters<'_> as alloy_sol_types::SolType>::abi_decode_sequence_validate(data).map(Self::new)
Self::abi_decode_raw_with_config(
data,
alloy_sol_types::abi::AbiDecoderConfig::new().validate(true),
)
}
}

Expand Down
27 changes: 21 additions & 6 deletions crates/sol-macro-expander/src/expand/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,19 +155,21 @@ pub(super) fn expand(cx: &ExpCtxt<'_>, function: &ItemFunction) -> Result<TokenS
quote!(#decode_sequence.map(Into::into))
};

let decode_sequence_validate = quote!(
<Self::ReturnTuple<'_> as alloy_sol_types::SolType>::abi_decode_sequence_validate(data)
let decode_sequence_with_config = quote!(
<Self::ReturnTuple<'_> as alloy_sol_types::SolType>::abi_decode_sequence_with_config(
data, config,
)
);
let decode_returns_validate = if is_single_return {
let decode_returns_with_config = if is_single_return {
let name = anon_name((0, returns[0].name.as_ref()));
quote! {
#decode_sequence_validate.map(|r| {
#decode_sequence_with_config.map(|r| {
let r: #return_name = r.into();
r.#name
})
}
} else {
quote!(#decode_sequence_validate.map(Into::into))
quote!(#decode_sequence_with_config.map(Into::into))
};

let tokens = quote! {
Expand Down Expand Up @@ -228,8 +230,21 @@ pub(super) fn expand(cx: &ExpCtxt<'_>, function: &ItemFunction) -> Result<TokenS
}

#[inline]
fn abi_decode_returns_with_config(
data: &[u8],
config: alloy_sol_types::abi::AbiDecoderConfig,
) -> alloy_sol_types::Result<Self::Return> {
#decode_returns_with_config
}

#[inline]
// TODO: Deprecate in favor of a validating decoder configuration.
// #[deprecated(note = "use a validating decoder configuration")]
fn abi_decode_returns_validate(data: &[u8]) -> alloy_sol_types::Result<Self::Return> {
#decode_returns_validate
Self::abi_decode_returns_with_config(
data,
alloy_sol_types::abi::AbiDecoderConfig::new().validate(true),
)
}
}

Expand Down
Loading
Loading