wasm/validation/modules/
imports.rs

1use crate::{
2    core::{
3        decoding::reader::WasmDecoder,
4        structure::modules::{
5            imports::{Import, ImportDesc},
6            indices::{IdxVec, TypeIdx},
7        },
8    },
9    DecodingError, ExternType, FuncType, GlobalType, MemType, Module, TableType, ValidationError,
10};
11
12impl<'wasm> Import<'wasm> {
13    pub fn decode_and_validate(
14        wasm: &mut WasmDecoder<'wasm>,
15        c_types: &IdxVec<TypeIdx, FuncType>,
16    ) -> Result<Self, ValidationError> {
17        let module_name = wasm.decode_name()?;
18        let name = wasm.decode_name()?;
19        let desc = ImportDesc::decode_and_validate(wasm, c_types)?;
20
21        Ok(Self {
22            module_name,
23            name,
24            desc,
25        })
26    }
27}
28
29impl ImportDesc {
30    pub fn decode_and_validate(
31        wasm: &mut WasmDecoder,
32        c_types: &IdxVec<TypeIdx, FuncType>,
33    ) -> Result<Self, ValidationError> {
34        let desc = match wasm.decode_u8()? {
35            0x00 => Self::Func(TypeIdx::decode_and_validate(wasm, c_types)?),
36            // https://webassembly.github.io/spec/core/binary/types.html#table-types
37            0x01 => Self::Table(TableType::decode_and_validate(wasm)?),
38            0x02 => Self::Mem(MemType::decode_and_validate(wasm)?),
39            0x03 => Self::Global(GlobalType::decode(wasm)?),
40            other => return Err(DecodingError::MalformedImportDescDiscriminator(other).into()),
41        };
42
43        Ok(desc)
44    }
45
46    /// returns the external type of `self` according to typing relation,
47    /// taking `validation_info` as validation context C
48    ///
49    /// # Safety
50    ///
51    /// The caller must ensure that `self` comes from the same
52    /// [`Module`] that is passed as an argument here.
53    pub unsafe fn extern_type(&self, module: &Module) -> ExternType {
54        match self {
55            ImportDesc::Func(type_idx) => {
56                // unlike ExportDescs, these directly refer to the types section
57                // since a corresponding function entry in function section or body
58                // in code section does not exist for these
59
60                // SAFETY: The caller ensures that the current `ImportDesc` comes from the same
61                // `Module`. Because all type indices contained by a `Module` must always be valid,
62                // this is safe.
63                let func_type = unsafe { module.types.get(*type_idx) };
64                // TODO ugly clone that should disappear when types are directly parsed from bytecode instead of vector copies
65                ExternType::Func(func_type.clone())
66            }
67            ImportDesc::Table(ty) => ExternType::Table(*ty),
68            ImportDesc::Mem(ty) => ExternType::Mem(*ty),
69            ImportDesc::Global(ty) => ExternType::Global(*ty),
70        }
71    }
72}