      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141

    use crate::Error;
    use alloc::vec::Vec;
    use parity_wasm::elements::{
        BlockType, FunctionType, GlobalType, MemoryType, TableType, ValueType,
    };

    #[derive(Default, Debug)]
    pub struct ModuleContext {
        pub memories: Vec<MemoryType>,
        pub tables: Vec<TableType>,
        pub globals: Vec<GlobalType>,
        pub types: Vec<FunctionType>,
        pub func_type_indexes: Vec<u32>,
    }

    impl ModuleContext {
        pub fn memories(&self) -> &[MemoryType] {
            &self.memories
        }

        pub fn tables(&self) -> &[TableType] {
            &self.tables
        }

        pub fn globals(&self) -> &[GlobalType] {
            &self.globals
        }

        pub fn types(&self) -> &[FunctionType] {
            &self.types
        }

        pub fn func_type_indexes(&self) -> &[u32] {
            &self.func_type_indexes
        }

        pub fn require_memory(&self, idx: u32) -> Result<(), Error> {
            if self.memories().get(idx as usize).is_none() {
                return Err(Error(format!("Memory at index {} doesn't exists", idx)));
            }
            Ok(())
        }

        pub fn require_table(&self, idx: u32) -> Result<&TableType, Error> {
            self.tables()
                .get(idx as usize)
                .ok_or_else(|| Error(format!("Table at index {} doesn't exists", idx)))
        }

        pub fn require_function(&self, idx: u32) -> Result<(&[ValueType], BlockType), Error> {
            let ty_idx = self
                .func_type_indexes()
                .get(idx as usize)
                .ok_or_else(|| Error(format!("Function at index {} doesn't exists", idx)))?;
            self.require_function_type(*ty_idx)
        }

        pub fn require_function_type(&self, idx: u32) -> Result<(&[ValueType], BlockType), Error> {
            let ty = self
                .types()
                .get(idx as usize)
                .ok_or_else(|| Error(format!("Type at index {} doesn't exists", idx)))?;

            let params = ty.params();
            let return_ty = ty
                .return_type()
                .map(BlockType::Value)
                .unwrap_or(BlockType::NoResult);
            Ok((params, return_ty))
        }

        pub fn require_global(&self, idx: u32, mutability: Option<bool>) -> Result<&GlobalType, Error> {
            let global = self
                .globals()
                .get(idx as usize)
                .ok_or_else(|| Error(format!("Global at index {} doesn't exists", idx)))?;

            if let Some(expected_mutable) = mutability {
                if expected_mutable && !global.is_mutable() {
                    return Err(Error(format!("Expected global {} to be mutable", idx)));
                }
                if !expected_mutable && global.is_mutable() {
                    return Err(Error(format!("Expected global {} to be immutable", idx)));
                }
            }
            Ok(global)
        }
    }

    #[derive(Default)]
    pub struct ModuleContextBuilder {
        memories: Vec<MemoryType>,
        tables: Vec<TableType>,
        globals: Vec<GlobalType>,
        types: Vec<FunctionType>,
        func_type_indexes: Vec<u32>,
    }

    impl ModuleContextBuilder {
        pub fn new() -> ModuleContextBuilder {
            ModuleContextBuilder::default()
        }

        pub fn push_memory(&mut self, memory: MemoryType) {
            self.memories.push(memory);
        }

        pub fn push_table(&mut self, table: TableType) {
            self.tables.push(table);
        }

        pub fn push_global(&mut self, global: GlobalType) {
            self.globals.push(global);
        }

        pub fn set_types(&mut self, types: Vec<FunctionType>) {
            self.types = types;
        }

        pub fn push_func_type_index(&mut self, func_type_index: u32) {
            self.func_type_indexes.push(func_type_index);
        }

        pub fn build(self) -> ModuleContext {
            let ModuleContextBuilder {
                memories,
                tables,
                globals,
                types,
                func_type_indexes,
            } = self;

            ModuleContext {
                memories,
                tables,
                globals,
                types,
                func_type_indexes,
            }
        }
    }

# Help

## Keyboard Shortcuts

`?`
  Show this help dialog
`S`
  Focus the search field
`↑`
  Move up in search results
`↓`
  Move down in search results
`↹`
  Switch tab
`⏎`
  Go to active search result
`+`
  Expand all sections
`-`
  Collapse all sections

## Search Tricks

Prefix searches with a type followed by a colon (e.g., `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g., `vec -> usize` or `* -> vec`)

Search multiple things at once by splitting your query with comma (e.g., `str,u8` or `String,struct:Vec,test`)