(cx: &mut LiftContext<'_>, ty: TypeListIndex, ptr: usize, len: usize)
| 953 | } |
| 954 | |
| 955 | fn load_list(cx: &mut LiftContext<'_>, ty: TypeListIndex, ptr: usize, len: usize) -> Result<Val> { |
| 956 | let elem = cx.types[ty].element; |
| 957 | let abi = cx.types.canonical_abi(&elem); |
| 958 | let element_size = usize::try_from(abi.size32).unwrap(); |
| 959 | let element_alignment = abi.align32; |
| 960 | |
| 961 | match len |
| 962 | .checked_mul(element_size) |
| 963 | .and_then(|len| ptr.checked_add(len)) |
| 964 | { |
| 965 | Some(n) if n <= cx.memory().len() => cx.consume_fuel_array(len, size_of::<Val>())?, |
| 966 | _ => bail!("list pointer/length out of bounds of memory"), |
| 967 | } |
| 968 | if ptr % usize::try_from(element_alignment)? != 0 { |
| 969 | bail!("list pointer is not aligned") |
| 970 | } |
| 971 | |
| 972 | Ok(Val::List( |
| 973 | (0..len) |
| 974 | .map(|index| { |
| 975 | Val::load( |
| 976 | cx, |
| 977 | elem, |
| 978 | &cx.memory()[ptr + (index * element_size)..][..element_size], |
| 979 | ) |
| 980 | }) |
| 981 | .collect::<Result<_>>()?, |
| 982 | )) |
| 983 | } |
| 984 | |
| 985 | fn load_map(cx: &mut LiftContext<'_>, ty: TypeMapIndex, ptr: usize, len: usize) -> Result<Val> { |
| 986 | // Maps are stored as list<tuple<k, v>> in canonical ABI |
no test coverage detected