1use crate::cast::{CastSign, Overflow};
7use crate::error::AssemblerError;
8use crate::items::LabelRef;
9use crate::resolver::Resolver;
10use crate::strings::{MysteryString, Utf32String};
11use bytes::BufMut;
12
13#[derive(Debug, Clone)]
15pub enum DecodeNode<L> {
16 Branch(Box<DecodeNode<L>>, Box<DecodeNode<L>>),
18 StringTerminator,
20 MysteryChar(u8),
23 MysteryString(MysteryString),
26 UnicodeChar(char),
28 Utf32String(Utf32String),
30 IndirectRef(LabelRef<L>),
33 DoubleIndirectRef(LabelRef<L>),
36 IndirectRefWithArgs(LabelRef<L>, Vec<DecodeArg<L>>),
39 DoubleIndirectRefWithArgs(LabelRef<L>, Vec<DecodeArg<L>>),
42}
43
44pub(crate) enum ResolvedDecodeNode {
45 Branch(Box<ResolvedDecodeNode>, Box<ResolvedDecodeNode>),
46 StringTerminator,
47 MysteryChar(u8),
48 MysteryString(MysteryString),
49 UnicodeChar(char),
50 Utf32String(Utf32String),
51 IndirectRef(u32),
52 DoubleIndirectRef(u32),
53 IndirectRefWithArgs(u32, Vec<i32>),
54 DoubleIndirectRefWithArgs(u32, Vec<i32>),
55}
56
57#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
59pub enum DecodeArg<L> {
60 Label(LabelRef<L>),
62 Literal(i32),
64}
65
66impl<L> DecodeArg<L> {
67 pub fn map<F, M>(self, f: F) -> DecodeArg<M>
69 where
70 F: FnMut(L) -> M,
71 {
72 match self {
73 DecodeArg::Label(l) => DecodeArg::Label(l.map(f)),
74 DecodeArg::Literal(x) => DecodeArg::Literal(x),
75 }
76 }
77
78 pub(crate) fn resolve<R>(&self, resolver: &R) -> Result<i32, AssemblerError<L>>
79 where
80 R: Resolver<Label = L>,
81 {
82 Ok(match self {
83 DecodeArg::Label(l) => l.resolve_absolute(resolver)?.cast_sign(),
84 DecodeArg::Literal(x) => *x,
85 })
86 }
87}
88
89impl<L> DecodeNode<L> {
90 pub fn map<F, M>(self, mut f: F) -> DecodeNode<M>
92 where
93 F: FnMut(L) -> M,
94 {
95 self.map_inner(&mut f)
96 }
97
98 fn map_inner<F, M>(self, f: &mut F) -> DecodeNode<M>
102 where
103 F: FnMut(L) -> M,
104 {
105 match self {
106 DecodeNode::Branch(left, right) => DecodeNode::Branch(
107 Box::new(left.map_inner(&mut *f)),
108 Box::new(right.map_inner(&mut *f)),
109 ),
110 DecodeNode::StringTerminator => DecodeNode::StringTerminator,
111 DecodeNode::MysteryChar(x) => DecodeNode::MysteryChar(x),
112 DecodeNode::MysteryString(x) => DecodeNode::MysteryString(x),
113 DecodeNode::UnicodeChar(x) => DecodeNode::UnicodeChar(x),
114 DecodeNode::Utf32String(x) => DecodeNode::Utf32String(x),
115 DecodeNode::IndirectRef(r) => DecodeNode::IndirectRef(r.map(f)),
116 DecodeNode::DoubleIndirectRef(r) => DecodeNode::DoubleIndirectRef(r.map(f)),
117 DecodeNode::IndirectRefWithArgs(r, args) => DecodeNode::IndirectRefWithArgs(
118 r.map(&mut *f),
119 args.into_iter().map(|arg| arg.map(&mut *f)).collect(),
120 ),
121 DecodeNode::DoubleIndirectRefWithArgs(r, args) => {
122 DecodeNode::DoubleIndirectRefWithArgs(
123 r.map(&mut *f),
124 args.into_iter().map(|arg| arg.map(&mut *f)).collect(),
125 )
126 }
127 }
128 }
129
130 pub(crate) fn len(&self) -> usize {
131 match self {
132 DecodeNode::Branch(left, right) => left.len() + right.len() + 9,
133 DecodeNode::StringTerminator => 1,
134 DecodeNode::MysteryChar(_) => 2,
135 DecodeNode::MysteryString(s) => s.len() + 2,
136 DecodeNode::UnicodeChar(_) => 5,
137 DecodeNode::Utf32String(s) => s.byte_len() + 5,
138 DecodeNode::IndirectRef(_) => 5,
139 DecodeNode::DoubleIndirectRef(_) => 5,
140 DecodeNode::IndirectRefWithArgs(_, args) => 4 * args.len() + 9,
141 DecodeNode::DoubleIndirectRefWithArgs(_, args) => 4 * args.len() + 9,
142 }
143 }
144
145 pub(crate) fn resolve<R>(&self, resolver: &R) -> Result<ResolvedDecodeNode, AssemblerError<L>>
146 where
147 R: Resolver<Label = L>,
148 {
149 Ok(match self {
150 DecodeNode::Branch(left, right) => ResolvedDecodeNode::Branch(
151 Box::new(left.resolve(resolver)?),
152 Box::new(right.resolve(resolver)?),
153 ),
154 DecodeNode::StringTerminator => ResolvedDecodeNode::StringTerminator,
155 DecodeNode::MysteryChar(c) => ResolvedDecodeNode::MysteryChar(*c),
156 DecodeNode::MysteryString(s) => ResolvedDecodeNode::MysteryString(s.clone()),
157 DecodeNode::UnicodeChar(c) => ResolvedDecodeNode::UnicodeChar(*c),
158 DecodeNode::Utf32String(s) => ResolvedDecodeNode::Utf32String(s.clone()),
159 DecodeNode::IndirectRef(r) => {
160 ResolvedDecodeNode::IndirectRef(r.resolve_absolute(resolver)?)
161 }
162 DecodeNode::DoubleIndirectRef(r) => {
163 ResolvedDecodeNode::DoubleIndirectRef(r.resolve_absolute(resolver)?)
164 }
165 DecodeNode::IndirectRefWithArgs(r, args) => {
166 u32::try_from(args.len()).overflow()?; let mut newargs = Vec::with_capacity(args.len());
168 for arg in args {
169 newargs.push(arg.resolve(resolver)?);
170 }
171
172 ResolvedDecodeNode::IndirectRefWithArgs(r.resolve_absolute(resolver)?, newargs)
173 }
174 DecodeNode::DoubleIndirectRefWithArgs(r, args) => {
175 u32::try_from(args.len()).overflow()?;
176 let mut newargs = Vec::with_capacity(args.len());
177 for arg in args {
178 newargs.push(arg.resolve(resolver)?);
179 }
180
181 ResolvedDecodeNode::DoubleIndirectRefWithArgs(
182 r.resolve_absolute(resolver)?,
183 newargs,
184 )
185 }
186 })
187 }
188}
189
190impl ResolvedDecodeNode {
191 pub(crate) fn count_nodes(&self) -> usize {
192 match self {
193 ResolvedDecodeNode::Branch(left, right) => 1 + left.count_nodes() + right.count_nodes(),
194 _ => 1,
195 }
196 }
197
198 pub(crate) fn len(&self) -> usize {
199 match self {
200 ResolvedDecodeNode::Branch(left, right) => left.len() + right.len() + 9,
201 ResolvedDecodeNode::StringTerminator => 1,
202 ResolvedDecodeNode::MysteryChar(_) => 2,
203 ResolvedDecodeNode::MysteryString(s) => s.len() + 2,
204 ResolvedDecodeNode::UnicodeChar(_) => 5,
205 ResolvedDecodeNode::Utf32String(s) => s.byte_len() + 5,
206 ResolvedDecodeNode::IndirectRef(_) => 5,
207 ResolvedDecodeNode::DoubleIndirectRef(_) => 5,
208 ResolvedDecodeNode::IndirectRefWithArgs(_, args) => 4 * args.len() + 9,
209 ResolvedDecodeNode::DoubleIndirectRefWithArgs(_, args) => 4 * args.len() + 9,
210 }
211 }
212
213 pub(crate) fn serialize<B>(&self, num: u32, mut buf: B)
214 where
215 B: BufMut,
216 {
217 self.serialize_inner(num, &mut buf)
218 }
219
220 fn serialize_inner<B>(&self, num: u32, buf: &mut B)
221 where
222 B: BufMut,
223 {
224 match self {
225 ResolvedDecodeNode::Branch(left, right) => {
226 let panic_msg = "decode tables with >= 2**32 nodes should have been rejected before serialization";
227 let left_num = num.checked_add(1).expect(panic_msg);
228 let right_num = left_num
229 .checked_add(left.count_nodes().try_into().expect(panic_msg))
230 .expect(panic_msg);
231 buf.put_u8(0);
232 left.serialize_inner(left_num, &mut *buf);
233 right.serialize_inner(right_num, &mut *buf);
234 }
235 ResolvedDecodeNode::StringTerminator => {
236 buf.put_u8(1);
237 }
238 ResolvedDecodeNode::MysteryChar(x) => {
239 buf.put_u8(2);
240 buf.put_u8(*x);
241 }
242 ResolvedDecodeNode::MysteryString(s) => {
243 buf.put_u8(3);
244 buf.put(s.to_bytes());
245 buf.put_u8(0);
246 }
247 ResolvedDecodeNode::UnicodeChar(c) => {
248 buf.put_u8(4);
249 buf.put_u32((*c).into());
250 }
251 ResolvedDecodeNode::Utf32String(s) => {
252 buf.put_u8(5);
253 buf.put(s.to_bytes());
254 buf.put_u32(0);
255 }
256 ResolvedDecodeNode::IndirectRef(r) => {
257 buf.put_u8(8);
258 buf.put_u32(*r);
259 }
260 ResolvedDecodeNode::DoubleIndirectRef(r) => {
261 buf.put_u8(9);
262 buf.put_u32(*r);
263 }
264 ResolvedDecodeNode::IndirectRefWithArgs(r, args) => {
265 buf.put_u8(0xa);
266 buf.put_u32(*r);
267 buf.put_u32(
268 args.len().try_into().expect(
269 "refs with >= 2**32 args should have been rejected during resolution",
270 ),
271 );
272 for arg in args {
273 buf.put_i32(*arg)
274 }
275 }
276 ResolvedDecodeNode::DoubleIndirectRefWithArgs(r, args) => {
277 buf.put_u8(0xb);
278 buf.put_u32(*r);
279 buf.put_u32(
280 args.len().try_into().expect(
281 "refs with >= 2**32 args should have been rejected during resolution",
282 ),
283 );
284 for arg in args {
285 buf.put_i32(*arg)
286 }
287 }
288 }
289 }
290}