1use crate::core::*;
2use crate::kw;
3use crate::parser::{Lookahead1, Parse, Parser, Peek, Result};
4use crate::token::*;
5
6#[derive(Debug)]
8pub struct Memory<'a> {
9 pub span: Span,
11 pub id: Option<Id<'a>>,
13 pub name: Option<NameAnnotation<'a>>,
15 pub exports: InlineExport<'a>,
18 pub kind: MemoryKind<'a>,
20}
21
22#[derive(Debug)]
24pub enum MemoryKind<'a> {
25 #[allow(missing_docs)]
27 Import {
28 import: InlineImport<'a>,
29 ty: MemoryType,
30 },
31
32 Normal(MemoryType),
34
35 Inline {
37 is64: bool,
39 data: Vec<DataVal<'a>>,
41 page_size_log2: Option<u32>,
43 },
44}
45
46impl<'a> Parse<'a> for Memory<'a> {
47 fn parse(parser: Parser<'a>) -> Result<Self> {
48 let span = parser.parse::<kw::memory>()?.0;
49 let id = parser.parse()?;
50 let name = parser.parse()?;
51 let exports = parser.parse()?;
52
53 let mut l = parser.lookahead1();
59 let kind = if let Some(import) = parser.parse()? {
60 MemoryKind::Import {
61 import,
62 ty: parser.parse()?,
63 }
64 } else if l.peek::<LParen>()?
65 || ((parser.peek::<kw::i32>()? || parser.peek::<kw::i64>()?)
66 && parser.peek2::<LParen>()?)
67 {
68 let is64 = if parser.parse::<Option<kw::i32>>()?.is_some() {
69 false
70 } else {
71 parser.parse::<Option<kw::i64>>()?.is_some()
72 };
73 let page_size_log2 = page_size(parser)?;
74 let data = parser.parens(|parser| {
75 parser.parse::<kw::data>()?;
76 let mut data = Vec::new();
77 while !parser.is_empty() {
78 data.push(parser.parse()?);
79 }
80 Ok(data)
81 })?;
82 MemoryKind::Inline {
83 data,
84 is64,
85 page_size_log2,
86 }
87 } else if l.peek::<u32>()? || l.peek::<kw::i32>()? || l.peek::<kw::i64>()? {
88 MemoryKind::Normal(parser.parse()?)
89 } else {
90 return Err(l.error());
91 };
92 Ok(Memory {
93 span,
94 id,
95 name,
96 exports,
97 kind,
98 })
99 }
100}
101
102#[derive(Debug)]
104pub struct Data<'a> {
105 pub span: Span,
107
108 pub id: Option<Id<'a>>,
110
111 pub name: Option<NameAnnotation<'a>>,
113
114 pub kind: DataKind<'a>,
116
117 pub data: Vec<DataVal<'a>>,
120}
121
122#[derive(Debug)]
124pub enum DataKind<'a> {
125 Passive,
128
129 Active {
132 memory: Index<'a>,
134
135 offset: Expression<'a>,
137 },
138}
139
140impl<'a> Parse<'a> for Data<'a> {
141 fn parse(parser: Parser<'a>) -> Result<Self> {
142 let span = parser.parse::<kw::data>()?.0;
143 let id = parser.parse()?;
144 let name = parser.parse()?;
145
146 let kind = if parser.peek::<&[u8]>()? || parser.peek::<RParen>()? {
147 DataKind::Passive
148
149 } else {
152 let memory = if parser.peek::<u32>()? {
153 Index::Num(parser.parse()?, span)
158 } else if parser.peek2::<kw::memory>()? {
159 parser.parens(|p| {
160 p.parse::<kw::memory>()?;
161 p.parse()
162 })?
163 } else {
164 Index::Num(0, span)
165 };
166 let offset = parser.parens(|parser| {
167 if parser.peek::<kw::offset>()? {
168 parser.parse::<kw::offset>()?;
169 parser.parse()
170 } else {
171 let insn = parser.parse()?;
175 if parser.is_empty() {
176 return Ok(Expression::one(insn));
177 }
178
179 let mut expr: Expression = parser.parse()?;
191 let mut instrs = Vec::from(expr.instrs);
192 instrs.push(insn);
193 expr.instrs = instrs.into();
194 Ok(expr)
195 }
196 })?;
197 DataKind::Active { memory, offset }
198 };
199
200 let mut data = Vec::new();
201 while !parser.is_empty() {
202 data.push(parser.parse()?);
203 }
204 Ok(Data {
205 span,
206 id,
207 name,
208 kind,
209 data,
210 })
211 }
212}
213
214#[derive(Debug)]
216#[allow(missing_docs)]
217pub enum DataVal<'a> {
218 String(&'a [u8]),
219 Integral(Vec<u8>),
220}
221
222impl DataVal<'_> {
223 pub fn len(&self) -> usize {
226 match self {
227 DataVal::String(s) => s.len(),
228 DataVal::Integral(s) => s.len(),
229 }
230 }
231
232 pub fn push_onto(&self, dst: &mut Vec<u8>) {
234 match self {
235 DataVal::String(s) => dst.extend_from_slice(s),
236 DataVal::Integral(s) => dst.extend_from_slice(s),
237 }
238 }
239}
240
241impl<'a> Parse<'a> for DataVal<'a> {
242 fn parse(parser: Parser<'a>) -> Result<Self> {
243 if !parser.peek::<LParen>()? {
244 return Ok(DataVal::String(parser.parse()?));
245 }
246
247 return parser.parens(|p| {
248 let mut result = Vec::new();
249 let mut lookahead = p.lookahead1();
250 let l = &mut lookahead;
251 let r = &mut result;
252 if consume::<kw::i8, i8, _>(p, l, r, |u, v| v.push(u as u8))?
253 || consume::<kw::i16, i16, _>(p, l, r, |u, v| v.extend(&u.to_le_bytes()))?
254 || consume::<kw::i32, i32, _>(p, l, r, |u, v| v.extend(&u.to_le_bytes()))?
255 || consume::<kw::i64, i64, _>(p, l, r, |u, v| v.extend(&u.to_le_bytes()))?
256 || consume::<kw::f32, F32, _>(p, l, r, |u, v| v.extend(&u.bits.to_le_bytes()))?
257 || consume::<kw::f64, F64, _>(p, l, r, |u, v| v.extend(&u.bits.to_le_bytes()))?
258 || consume::<kw::v128, V128Const, _>(p, l, r, |u, v| v.extend(&u.to_le_bytes()))?
259 {
260 Ok(DataVal::Integral(result))
261 } else {
262 Err(lookahead.error())
263 }
264 });
265
266 fn consume<'a, T: Peek + Parse<'a>, U: Parse<'a>, F>(
267 parser: Parser<'a>,
268 lookahead: &mut Lookahead1<'a>,
269 dst: &mut Vec<u8>,
270 push: F,
271 ) -> Result<bool>
272 where
273 F: Fn(U, &mut Vec<u8>),
274 {
275 if !lookahead.peek::<T>()? {
276 return Ok(false);
277 }
278 parser.parse::<T>()?;
279 while !parser.is_empty() {
280 let val = parser.parse::<U>()?;
281 push(val, dst);
282 }
283 Ok(true)
284 }
285 }
286}