wasmi_validation/
context.rs1use crate::Error;
2use alloc::vec::Vec;
3use parity_wasm::elements::{
4 BlockType,
5 FunctionType,
6 GlobalType,
7 MemoryType,
8 TableType,
9 ValueType,
10};
11
12#[derive(Default, Debug)]
13pub struct ModuleContext {
14 pub memories: Vec<MemoryType>,
15 pub tables: Vec<TableType>,
16 pub globals: Vec<GlobalType>,
17 pub types: Vec<FunctionType>,
18 pub func_type_indexes: Vec<u32>,
19}
20
21impl ModuleContext {
22 pub fn memories(&self) -> &[MemoryType] {
23 &self.memories
24 }
25
26 pub fn tables(&self) -> &[TableType] {
27 &self.tables
28 }
29
30 pub fn globals(&self) -> &[GlobalType] {
31 &self.globals
32 }
33
34 pub fn types(&self) -> &[FunctionType] {
35 &self.types
36 }
37
38 pub fn func_type_indexes(&self) -> &[u32] {
39 &self.func_type_indexes
40 }
41
42 pub fn require_memory(&self, idx: u32) -> Result<(), Error> {
43 if self.memories().get(idx as usize).is_none() {
44 return Err(Error(format!("Memory at index {} doesn't exists", idx)));
45 }
46 Ok(())
47 }
48
49 pub fn require_table(&self, idx: u32) -> Result<&TableType, Error> {
50 self.tables()
51 .get(idx as usize)
52 .ok_or_else(|| Error(format!("Table at index {} doesn't exists", idx)))
53 }
54
55 pub fn require_function(&self, idx: u32) -> Result<(&[ValueType], BlockType), Error> {
56 let ty_idx = self
57 .func_type_indexes()
58 .get(idx as usize)
59 .ok_or_else(|| Error(format!("Function at index {} doesn't exists", idx)))?;
60 self.require_function_type(*ty_idx)
61 }
62
63 pub fn require_function_type(&self, idx: u32) -> Result<(&[ValueType], BlockType), Error> {
64 let ty = self
65 .types()
66 .get(idx as usize)
67 .ok_or_else(|| Error(format!("Type at index {} doesn't exists", idx)))?;
68
69 let params = ty.params();
70 let return_ty = ty
71 .results()
72 .first()
73 .map(|vty| BlockType::Value(*vty))
74 .unwrap_or(BlockType::NoResult);
75 Ok((params, return_ty))
76 }
77
78 pub fn require_global(&self, idx: u32, mutability: Option<bool>) -> Result<&GlobalType, Error> {
79 let global = self
80 .globals()
81 .get(idx as usize)
82 .ok_or_else(|| Error(format!("Global at index {} doesn't exists", idx)))?;
83
84 if let Some(expected_mutable) = mutability {
85 if expected_mutable && !global.is_mutable() {
86 return Err(Error(format!("Expected global {} to be mutable", idx)));
87 }
88 if !expected_mutable && global.is_mutable() {
89 return Err(Error(format!("Expected global {} to be immutable", idx)));
90 }
91 }
92 Ok(global)
93 }
94}
95
96#[derive(Default)]
97pub struct ModuleContextBuilder {
98 memories: Vec<MemoryType>,
99 tables: Vec<TableType>,
100 globals: Vec<GlobalType>,
101 types: Vec<FunctionType>,
102 func_type_indexes: Vec<u32>,
103}
104
105impl ModuleContextBuilder {
106 pub fn new() -> ModuleContextBuilder {
107 ModuleContextBuilder::default()
108 }
109
110 pub fn push_memory(&mut self, memory: MemoryType) {
111 self.memories.push(memory);
112 }
113
114 pub fn push_table(&mut self, table: TableType) {
115 self.tables.push(table);
116 }
117
118 pub fn push_global(&mut self, global: GlobalType) {
119 self.globals.push(global);
120 }
121
122 pub fn set_types(&mut self, types: Vec<FunctionType>) {
123 self.types = types;
124 }
125
126 pub fn push_func_type_index(&mut self, func_type_index: u32) {
127 self.func_type_indexes.push(func_type_index);
128 }
129
130 pub fn build(self) -> ModuleContext {
131 let ModuleContextBuilder {
132 memories,
133 tables,
134 globals,
135 types,
136 func_type_indexes,
137 } = self;
138
139 ModuleContext {
140 memories,
141 tables,
142 globals,
143 types,
144 func_type_indexes,
145 }
146 }
147}