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
use super::{InitExpr, MemoryIdx};
use crate::errors::ModuleError;
use alloc::sync::Arc;
/// A Wasm [`Module`] data segment.
///
/// [`Module`]: [`super::Module`]
#[derive(Debug)]
pub struct DataSegment {
/// The kind of the data segment.
kind: DataSegmentKind,
/// The bytes of the data segment.
bytes: Arc<[u8]>,
}
/// The kind of a Wasm module [`DataSegment`].
#[derive(Debug)]
pub enum DataSegmentKind {
/// A passive data segment from the `bulk-memory` Wasm proposal.
Passive,
/// An active data segment that is initialized upon module instantiation.
Active(ActiveDataSegment),
}
/// An active data segment.
#[derive(Debug)]
pub struct ActiveDataSegment {
/// The linear memory that is to be initialized with this active segment.
memory_index: MemoryIdx,
/// The offset at which the data segment is initialized.
offset: InitExpr,
}
impl ActiveDataSegment {
/// Returns the Wasm module memory index that is to be initialized.
pub fn memory_index(&self) -> MemoryIdx {
self.memory_index
}
/// Returns the offset expression of the [`ActiveDataSegment`].
pub fn offset(&self) -> &InitExpr {
&self.offset
}
}
impl TryFrom<wasmparser::DataKind<'_>> for DataSegmentKind {
type Error = ModuleError;
fn try_from(data_kind: wasmparser::DataKind<'_>) -> Result<Self, Self::Error> {
match data_kind {
wasmparser::DataKind::Active {
memory_index,
offset_expr,
} => {
let memory_index = MemoryIdx(memory_index);
let offset = InitExpr::new(offset_expr);
Ok(Self::Active(ActiveDataSegment {
memory_index,
offset,
}))
}
wasmparser::DataKind::Passive => Ok(Self::Passive),
}
}
}
impl TryFrom<wasmparser::Data<'_>> for DataSegment {
type Error = ModuleError;
fn try_from(data: wasmparser::Data<'_>) -> Result<Self, Self::Error> {
let kind = DataSegmentKind::try_from(data.kind)?;
let bytes = data.data.into();
Ok(DataSegment { kind, bytes })
}
}
impl DataSegment {
/// Returns the [`DataSegmentKind`] of the [`DataSegment`].
pub fn kind(&self) -> &DataSegmentKind {
&self.kind
}
/// Returns the bytes of the [`DataSegment`].
pub fn bytes(&self) -> &[u8] {
&self.bytes[..]
}
/// Clone the underlying bytes of the [`DataSegment`].
pub fn clone_bytes(&self) -> Arc<[u8]> {
self.bytes.clone()
}
}