1use alloc::vec::Vec;
2
3use crate::{
4 core::{
5 indices::MemIdx,
6 reader::{
7 section_header::{SectionHeader, SectionTy},
8 types::{
9 data::{DataMode, DataModeActive, DataSegment},
10 global::GlobalType,
11 },
12 WasmReader,
13 },
14 },
15 read_constant_expression::read_constant_expression,
16 validation_stack::ValidationStack,
17 Result,
18};
19
20pub(super) fn validate_data_section(
22 wasm: &mut WasmReader,
23 section_header: SectionHeader,
24 imported_global_types: &[GlobalType],
25 no_of_total_memories: usize,
26 num_funcs: usize,
27) -> Result<Vec<DataSegment>> {
28 assert_eq!(section_header.ty, SectionTy::Data);
29
30 wasm.read_vec(|wasm| {
31 use crate::{NumType, ValType};
32 let mode = wasm.read_var_u32()?;
33 let data_sec: DataSegment = match mode {
34 0 => {
35 trace!("Data section: active {{ memory 0, offset e }}");
37 let mut valid_stack = ValidationStack::new();
38 let (offset, _) = {
39 read_constant_expression(
40 wasm,
41 &mut valid_stack,
42 imported_global_types,
43 num_funcs,
44 )?
45 };
46
47 valid_stack.assert_val_types(&[ValType::NumType(NumType::I32)], true)?;
48
49 let byte_vec = wasm.read_vec(|el| el.read_u8())?;
50
51 DataSegment {
53 mode: DataMode::Active(DataModeActive {
54 memory_idx: 0,
55 offset,
56 }),
57 init: byte_vec,
58 }
59 }
60 1 => {
61 trace!("Data section: passive");
64 DataSegment {
65 mode: DataMode::Passive,
66 init: wasm.read_vec(|el| el.read_u8())?,
67 }
68 }
69 2 => {
70 trace!("Data section: active {{ memory x, offset e }}");
71 let mem_idx = wasm.read_var_u32()? as MemIdx;
72 if mem_idx >= no_of_total_memories {
73 return Err(crate::Error::UnknownMemory);
74 }
75 assert!(
76 mem_idx == 0,
77 "Memory index is not 0 - it's {}! Multiple memories are NOT supported",
78 mem_idx
79 );
80
81 let mut valid_stack = ValidationStack::new();
82 let (offset, _) = {
83 read_constant_expression(
84 wasm,
85 &mut valid_stack,
86 imported_global_types,
87 num_funcs,
88 )?
89 };
90
91 valid_stack.assert_val_types(&[ValType::NumType(NumType::I32)], true)?;
92
93 let byte_vec = wasm.read_vec(|el| el.read_u8())?;
94
95 DataSegment {
96 mode: DataMode::Active(DataModeActive {
97 memory_idx: 0,
98 offset,
99 }),
100 init: byte_vec,
101 }
102 }
110 _ => unreachable!(),
111 };
112
113 trace!("{:?}", data_sec.init);
114 Ok(data_sec)
115 })
116}