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 {mem_idx}! Multiple memories are NOT supported"
78 );
79
80 let mut valid_stack = ValidationStack::new();
81 let (offset, _) = {
82 read_constant_expression(
83 wasm,
84 &mut valid_stack,
85 imported_global_types,
86 num_funcs,
87 )?
88 };
89
90 valid_stack.assert_val_types(&[ValType::NumType(NumType::I32)], true)?;
91
92 let byte_vec = wasm.read_vec(|el| el.read_u8())?;
93
94 DataSegment {
95 mode: DataMode::Active(DataModeActive {
96 memory_idx: 0,
97 offset,
98 }),
99 init: byte_vec,
100 }
101 }
109 _ => unreachable!(),
110 };
111
112 trace!("{:?}", data_sec.init);
113 Ok(data_sec)
114 })
115}