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