1use std::io::{Write,Cursor,Read};
19use std::ops::{Range};
20use leb128;
21use ron_uuid::UUID;
22use {
23 Statement,
24 Endianess,
25 Operation,
26 MemoryOperation,
27 FlowOperation,
28 Constant,
29 Variable,
30 Value,
31 StrRef,
32 Result,
33 RewriteControl,
34 NameRef,
35 Names,
36 Strings,
37 Segment,
38 SegmentRef,
39 Segments,
40 Constraint
41};
42
43#[derive(Clone,Debug)]
45pub struct Bitcode {
46 data: Vec<u8>,
47}
48macro_rules! encoding_rule {
107 ( $val:tt [ c , c ] => $a:expr, $b:expr, $res:expr, $data:expr ) => {{
108 let val = $val;
109 let a = $a;
110 let b = $b;
111 let res = $res;
112 let data = $data;
113
114 data.write(&[val])?;
115 Self::encode_constant(a,data)?;
116 Self::encode_constant(b,data)?;
117 Self::encode_variable(res,data)?;
118 }};
119 ( $val:tt [ c , v ] => $a:expr, $b:expr, $res:expr, $data:expr ) => {{
120 let val = $val;
121 let a = $a;
122 let b = $b;
123 let res = $res;
124 let data = $data;
125
126 data.write(&[val])?;
127 Self::encode_constant(a,data)?;
128 Self::encode_variable(b,data)?;
129 Self::encode_variable(res,data)?;
130 }};
131 ( $val:tt [ c , u ] => $a:expr, $res:expr, $data:expr ) => {{
132 let val = $val;
133 let a = $a;
134 let res = $res;
135 let data = $data;
136
137 data.write(&[val])?;
138 Self::encode_constant(a,data)?;
139 Self::encode_variable(res,data)?;
140 }};
141 ( $val:tt [ v , c ] => $a:expr, $b:expr, $res:expr, $data:expr ) => {{
142 let val = $val;
143 let a = $a;
144 let b = $b;
145 let res = $res;
146 let data = $data;
147
148 data.write(&[val])?;
149 Self::encode_variable(a,data)?;
150 Self::encode_constant(b,data)?;
151 Self::encode_variable(res,data)?;
152 }};
153 ( $val:tt [ v , v ] => $a:expr, $b:expr, $res:expr, $data:expr ) => {{
154 let val = $val;
155 let a = $a;
156 let b = $b;
157 let res = $res;
158 let data = $data;
159
160 data.write(&[val])?;
161 Self::encode_variable(a,data)?;
162 Self::encode_variable(b,data)?;
163 Self::encode_variable(res,data)?;
164 }};
165 ( $val:tt [ v , u ] => $a:expr, $res:expr, $data:expr ) => {{
166 let val = $val;
167 let a = $a;
168 let res = $res;
169 let data = $data;
170
171 data.write(&[val])?;
172 Self::encode_variable(a,data)?;
173 Self::encode_variable(res,data)?;
174 }};
175 ( $val:tt [ u , c ] => $b:expr, $res:expr, $data:expr ) => {{
176 let val = $val;
177 let b = $b;
178 let res = $res;
179 let data = $data;
180
181 data.write(&[val])?;
182 Self::encode_constant(b,data)?;
183 Self::encode_variable(res,data)?;
184 }};
185 ( $val:tt [ u , v ] => $b:expr, $res:expr, $data:expr ) => {{
186 let val = $val;
187 let b = $b;
188 let res = $res;
189 let data = $data;
190
191 data.write(&[val])?;
192 Self::encode_variable(b,data)?;
193 Self::encode_variable(res,data)?;
194 }};
195}
196
197impl Default for Bitcode {
198 fn default() -> Bitcode {
199 Bitcode{
200 data: Vec::new(),
201 }
202 }
203}
204
205impl Bitcode {
206 pub fn append<I: IntoIterator<Item=Statement> + Sized>(&mut self, i: I) -> Result<Range<usize>> {
208 let mut buf = Cursor::new(Vec::new());
209 let start = self.data.len();
210
211 for stmt in i {
212 Self::encode_statement(stmt,&mut buf)?;
213 }
214
215 self.data.extend(buf.into_inner().into_iter());
216 Ok(start..self.data.len())
217 }
218
219 pub fn new(v: Vec<Statement>) -> Result<Bitcode> {
221 let mut buf = Cursor::new(Vec::new());
222
223 for stmt in v {
224 Self::encode_statement(stmt,&mut buf)?;
225 }
226
227 Ok(Bitcode{ data: buf.into_inner() })
228 }
229
230 pub fn with_capacity(cap: usize) -> Bitcode {
232 Bitcode{
233 data: Vec::with_capacity(cap),
234 }
235 }
236
237 pub fn rewrite<F: FnMut(&mut Statement,&mut Names,&mut Strings,&mut Segments) -> Result<RewriteControl> + Sized>(&mut self, range: Range<usize>, names: &mut Names, strings: &mut Strings, segments: &mut Segments, mut func: F) -> Result<Range<usize>> {
239 if range.start == range.end { return Ok(range); }
240
241 debug!("rewrite bitcode in {:?}",range);
242 let mut read_pos = range.start;
243 let mut bytes_left = range.end - range.start;
244 let mut write_pos = range.start;
245 let mut tmp = Vec::with_capacity(10);
246
247 while bytes_left > 0 {
248 let mut stmt = {
249 debug!("read from {:?}",read_pos);
250 let mut read = Cursor::new(&self.data[read_pos..]);
251 let stmt = self.decode_statement(&mut read)?;
252
253 read_pos += read.position() as usize;
254 debug!("left: {:?}",bytes_left);
255 debug!("read {:?}",read.position());
256 debug!("read to {:?}",read_pos);
257 bytes_left -= read.position() as usize;
258 stmt
259 };
260
261 debug!("map {:?}",stmt);
262 match func(&mut stmt,names,strings,segments)? {
263 RewriteControl::Continue => { }
264 RewriteControl::Break => { return Ok(range.start..(read_pos + bytes_left)); }
265 }
266 debug!(" to {:?}",stmt);
267
268 {
269 let mut write = Cursor::new(tmp);
270
271 Self::encode_statement(stmt, &mut write)?;
272 tmp = write.into_inner();
273
274 if read_pos - write_pos < tmp.len() {
275 let diff = tmp.len() - (read_pos - write_pos);
276 debug!("make space for {} more bytes",diff);
277
278 self.data.reserve(diff);
279 for _ in 0..diff { self.data.insert(write_pos,42); }
281 read_pos += diff;
282 }
283 }
284
285 debug!("write {:?} at {}",tmp,write_pos);
287
288 {
289 let mut write = Cursor::new(&mut self.data[write_pos..]);
290 write_pos += write.write(&tmp)?;
291 tmp.clear();
292 }
293
294 if read_pos > write_pos {
295 debug!("remove {:?}",write_pos..read_pos);
296 self.data.drain(write_pos..read_pos);
297 read_pos = write_pos;
298 }
299
300 assert_eq!(read_pos, write_pos);
301 }
303
304 Ok(range.start..write_pos)
305 }
306
307 pub fn remove(&mut self, range: Range<usize>) {
309 self.data.drain(range);
310 }
311
312 pub fn insert(&mut self, pos: usize, stmts: Vec<Statement>) -> Result<Range<usize>> {
315 let data = Vec::with_capacity(stmts.len() * 10);
316 let mut cur = Cursor::new(data);
317
318 for stmt in stmts {
319 Self::encode_statement(stmt, &mut cur)?;
320 }
321
322 let buf = cur.into_inner();
323 let len = buf.len();
324
325 for b in buf.into_iter().rev() {
326 self.data.insert(pos,b);
327 }
328 Ok(pos..(pos + len))
330 }
331
332 fn encode_statement<W: Write>(stmt: Statement, data: &mut W) -> Result<()> {
333 use il::Operation::*;
334 use value::Value::*;
335
336 match stmt {
337 Statement::Expression{ op: Add(Constant(a),Constant(b)), result } => encoding_rule!( 0b00000_000 [c,c] => a, b, result, data ),
339 Statement::Expression{ op: Add(Constant(a),Variable(b)), result } => encoding_rule!( 0b00000_001 [c,v] => a, b, result, data ),
340 Statement::Expression{ op: Add(Constant(a),Undefined), result } => encoding_rule!( 0b00000_010 [c,u] => a, result, data ),
341 Statement::Expression{ op: Add(Variable(a),Constant(b)), result } => encoding_rule!( 0b00000_011 [v,c] => a, b, result, data ),
342 Statement::Expression{ op: Add(Variable(a),Variable(b)), result } => encoding_rule!( 0b00000_100 [v,v] => a, b, result, data ),
343 Statement::Expression{ op: Add(Variable(a),Undefined), result } => encoding_rule!( 0b00000_101 [v,u] => a, result, data ),
344 Statement::Expression{ op: Add(Undefined,Constant(b)), result } => encoding_rule!( 0b00000_110 [u,c] => b, result, data ),
345 Statement::Expression{ op: Add(Undefined,Variable(b)), result } => encoding_rule!( 0b00000_111 [u,v] => b, result, data ),
346 Statement::Expression{ op: Add(Undefined,Undefined), result } => {
347 Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
348 }
349
350 Statement::Expression{ op: Subtract(Constant(a),Constant(b)), result } => encoding_rule!( 0b00001_000 [c,c] => a, b, result, data ),
352 Statement::Expression{ op: Subtract(Constant(a),Variable(b)), result } => encoding_rule!( 0b00001_001 [c,v] => a, b, result, data ),
353 Statement::Expression{ op: Subtract(Constant(a),Undefined), result } => encoding_rule!( 0b00001_010 [c,u] => a, result, data ),
354 Statement::Expression{ op: Subtract(Variable(a),Constant(b)), result } => encoding_rule!( 0b00001_011 [v,c] => a, b, result, data ),
355 Statement::Expression{ op: Subtract(Variable(a),Variable(b)), result } => encoding_rule!( 0b00001_100 [v,v] => a, b, result, data ),
356 Statement::Expression{ op: Subtract(Variable(a),Undefined), result } => encoding_rule!( 0b00001_101 [v,u] => a, result, data ),
357 Statement::Expression{ op: Subtract(Undefined,Constant(b)), result } => encoding_rule!( 0b00001_110 [u,c] => b, result, data ),
358 Statement::Expression{ op: Subtract(Undefined,Variable(b)), result } => encoding_rule!( 0b00001_111 [u,v] => b, result, data ),
359 Statement::Expression{ op: Subtract(Undefined,Undefined), result } => {
360 Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
361 }
362
363 Statement::Expression{ op: Multiply(Constant(a),Constant(b)), result } => encoding_rule!( 0b00010_000 [c,c] => a, b, result, data ),
365 Statement::Expression{ op: Multiply(Constant(a),Variable(b)), result } => encoding_rule!( 0b00010_001 [c,v] => a, b, result, data ),
366 Statement::Expression{ op: Multiply(Constant(a),Undefined), result } => encoding_rule!( 0b00010_010 [c,u] => a, result, data ),
367 Statement::Expression{ op: Multiply(Variable(a),Constant(b)), result } => encoding_rule!( 0b00010_011 [v,c] => a, b, result, data ),
368 Statement::Expression{ op: Multiply(Variable(a),Variable(b)), result } => encoding_rule!( 0b00010_100 [v,v] => a, b, result, data ),
369 Statement::Expression{ op: Multiply(Variable(a),Undefined), result } => encoding_rule!( 0b00010_101 [v,u] => a, result, data ),
370 Statement::Expression{ op: Multiply(Undefined,Constant(b)), result } => encoding_rule!( 0b00010_110 [u,c] => b, result, data ),
371 Statement::Expression{ op: Multiply(Undefined,Variable(b)), result } => encoding_rule!( 0b00010_111 [u,v] => b, result, data ),
372 Statement::Expression{ op: Multiply(Undefined,Undefined), result } => {
373 Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
374 }
375
376 Statement::Expression{ op: DivideUnsigned(Constant(a),Constant(b)), result } => encoding_rule!( 0b00011_000 [c,c] => a, b, result, data ),
378 Statement::Expression{ op: DivideUnsigned(Constant(a),Variable(b)), result } => encoding_rule!( 0b00011_001 [c,v] => a, b, result, data ),
379 Statement::Expression{ op: DivideUnsigned(Constant(a),Undefined), result } => encoding_rule!( 0b00011_010 [c,u] => a, result, data ),
380 Statement::Expression{ op: DivideUnsigned(Variable(a),Constant(b)), result } => encoding_rule!( 0b00011_011 [v,c] => a, b, result, data ),
381 Statement::Expression{ op: DivideUnsigned(Variable(a),Variable(b)), result } => encoding_rule!( 0b00011_100 [v,v] => a, b, result, data ),
382 Statement::Expression{ op: DivideUnsigned(Variable(a),Undefined), result } => encoding_rule!( 0b00011_101 [v,u] => a, result, data ),
383 Statement::Expression{ op: DivideUnsigned(Undefined,Constant(b)), result } => encoding_rule!( 0b00011_110 [u,c] => b, result, data ),
384 Statement::Expression{ op: DivideUnsigned(Undefined,Variable(b)), result } => encoding_rule!( 0b00011_111 [u,v] => b, result, data ),
385 Statement::Expression{ op: DivideUnsigned(Undefined,Undefined), result } => {
386 Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
387 }
388
389 Statement::Expression{ op: DivideSigned(Constant(a),Constant(b)), result } => encoding_rule!( 0b00100_000 [c,c] => a, b, result, data ),
391 Statement::Expression{ op: DivideSigned(Constant(a),Variable(b)), result } => encoding_rule!( 0b00100_001 [c,v] => a, b, result, data ),
392 Statement::Expression{ op: DivideSigned(Constant(a),Undefined), result } => encoding_rule!( 0b00100_010 [c,u] => a, result, data ),
393 Statement::Expression{ op: DivideSigned(Variable(a),Constant(b)), result } => encoding_rule!( 0b00100_011 [v,c] => a, b, result, data ),
394 Statement::Expression{ op: DivideSigned(Variable(a),Variable(b)), result } => encoding_rule!( 0b00100_100 [v,v] => a, b, result, data ),
395 Statement::Expression{ op: DivideSigned(Variable(a),Undefined), result } => encoding_rule!( 0b00100_101 [v,u] => a, result, data ),
396 Statement::Expression{ op: DivideSigned(Undefined,Constant(b)), result } => encoding_rule!( 0b00100_110 [u,c] => b, result, data ),
397 Statement::Expression{ op: DivideSigned(Undefined,Variable(b)), result } => encoding_rule!( 0b00100_111 [u,v] => b, result, data ),
398 Statement::Expression{ op: DivideSigned(Undefined,Undefined), result } => {
399 Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
400 }
401
402 Statement::Expression{ op: ShiftLeft(Constant(a),Constant(b)), result } => encoding_rule!( 0b00101_000 [c,c] => a, b, result, data ),
404 Statement::Expression{ op: ShiftLeft(Constant(a),Variable(b)), result } => encoding_rule!( 0b00101_001 [c,v] => a, b, result, data ),
405 Statement::Expression{ op: ShiftLeft(Constant(a),Undefined), result } => encoding_rule!( 0b00101_010 [c,u] => a, result, data ),
406 Statement::Expression{ op: ShiftLeft(Variable(a),Constant(b)), result } => encoding_rule!( 0b00101_011 [v,c] => a, b, result, data ),
407 Statement::Expression{ op: ShiftLeft(Variable(a),Variable(b)), result } => encoding_rule!( 0b00101_100 [v,v] => a, b, result, data ),
408 Statement::Expression{ op: ShiftLeft(Variable(a),Undefined), result } => encoding_rule!( 0b00101_101 [v,u] => a, result, data ),
409 Statement::Expression{ op: ShiftLeft(Undefined,Constant(b)), result } => encoding_rule!( 0b00101_110 [u,c] => b, result, data ),
410 Statement::Expression{ op: ShiftLeft(Undefined,Variable(b)), result } => encoding_rule!( 0b00101_111 [u,v] => b, result, data ),
411 Statement::Expression{ op: ShiftLeft(Undefined,Undefined), result } => {
412 Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
413 }
414
415 Statement::Expression{ op: ShiftRightUnsigned(Constant(a),Constant(b)), result } => encoding_rule!( 0b00110_000 [c,c] => a, b, result, data ),
417 Statement::Expression{ op: ShiftRightUnsigned(Constant(a),Variable(b)), result } => encoding_rule!( 0b00110_001 [c,v] => a, b, result, data ),
418 Statement::Expression{ op: ShiftRightUnsigned(Constant(a),Undefined), result } => encoding_rule!( 0b00110_010 [c,u] => a, result, data ),
419 Statement::Expression{ op: ShiftRightUnsigned(Variable(a),Constant(b)), result } => encoding_rule!( 0b00110_011 [v,c] => a, b, result, data ),
420 Statement::Expression{ op: ShiftRightUnsigned(Variable(a),Variable(b)), result } => encoding_rule!( 0b00110_100 [v,v] => a, b, result, data ),
421 Statement::Expression{ op: ShiftRightUnsigned(Variable(a),Undefined), result } => encoding_rule!( 0b00110_101 [v,u] => a, result, data ),
422 Statement::Expression{ op: ShiftRightUnsigned(Undefined,Constant(b)), result } => encoding_rule!( 0b00110_110 [u,c] => b, result, data ),
423 Statement::Expression{ op: ShiftRightUnsigned(Undefined,Variable(b)), result } => encoding_rule!( 0b00110_111 [u,v] => b, result, data ),
424 Statement::Expression{ op: ShiftRightUnsigned(Undefined,Undefined), result } => {
425 Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
426 }
427
428 Statement::Expression{ op: ShiftRightSigned(Constant(a),Constant(b)), result } => encoding_rule!( 0b00111_000 [c,c] => a, b, result, data ),
430 Statement::Expression{ op: ShiftRightSigned(Constant(a),Variable(b)), result } => encoding_rule!( 0b00111_001 [c,v] => a, b, result, data ),
431 Statement::Expression{ op: ShiftRightSigned(Constant(a),Undefined), result } => encoding_rule!( 0b00111_010 [c,u] => a, result, data ),
432 Statement::Expression{ op: ShiftRightSigned(Variable(a),Constant(b)), result } => encoding_rule!( 0b00111_011 [v,c] => a, b, result, data ),
433 Statement::Expression{ op: ShiftRightSigned(Variable(a),Variable(b)), result } => encoding_rule!( 0b00111_100 [v,v] => a, b, result, data ),
434 Statement::Expression{ op: ShiftRightSigned(Variable(a),Undefined), result } => encoding_rule!( 0b00111_101 [v,u] => a, result, data ),
435 Statement::Expression{ op: ShiftRightSigned(Undefined,Constant(b)), result } => encoding_rule!( 0b00111_110 [u,c] => b, result, data ),
436 Statement::Expression{ op: ShiftRightSigned(Undefined,Variable(b)), result } => encoding_rule!( 0b00111_111 [u,v] => b, result, data ),
437 Statement::Expression{ op: ShiftRightSigned(Undefined,Undefined), result } => {
438 Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
439 }
440
441 Statement::Expression{ op: Modulo(Constant(a),Constant(b)), result } => encoding_rule!( 0b01000_000 [c,c] => a, b, result, data ),
443 Statement::Expression{ op: Modulo(Constant(a),Variable(b)), result } => encoding_rule!( 0b01000_001 [c,v] => a, b, result, data ),
444 Statement::Expression{ op: Modulo(Constant(a),Undefined), result } => encoding_rule!( 0b01000_010 [c,u] => a, result, data ),
445 Statement::Expression{ op: Modulo(Variable(a),Constant(b)), result } => encoding_rule!( 0b01000_011 [v,c] => a, b, result, data ),
446 Statement::Expression{ op: Modulo(Variable(a),Variable(b)), result } => encoding_rule!( 0b01000_100 [v,v] => a, b, result, data ),
447 Statement::Expression{ op: Modulo(Variable(a),Undefined), result } => encoding_rule!( 0b01000_101 [v,u] => a, result, data ),
448 Statement::Expression{ op: Modulo(Undefined,Constant(b)), result } => encoding_rule!( 0b01000_110 [u,c] => b, result, data ),
449 Statement::Expression{ op: Modulo(Undefined,Variable(b)), result } => encoding_rule!( 0b01000_111 [u,v] => b, result, data ),
450 Statement::Expression{ op: Modulo(Undefined,Undefined), result } => {
451 Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
452 }
453
454 Statement::Expression{ op: And(Constant(a),Constant(b)), result } => encoding_rule!( 0b01001_000 [c,c] => a, b, result, data ),
456 Statement::Expression{ op: And(Constant(a),Variable(b)), result } => encoding_rule!( 0b01001_001 [c,v] => a, b, result, data ),
457 Statement::Expression{ op: And(Constant(a),Undefined), result } => encoding_rule!( 0b01001_010 [c,u] => a, result, data ),
458 Statement::Expression{ op: And(Variable(a),Constant(b)), result } => encoding_rule!( 0b01001_011 [v,c] => a, b, result, data ),
459 Statement::Expression{ op: And(Variable(a),Variable(b)), result } => encoding_rule!( 0b01001_100 [v,v] => a, b, result, data ),
460 Statement::Expression{ op: And(Variable(a),Undefined), result } => encoding_rule!( 0b01001_101 [v,u] => a, result, data ),
461 Statement::Expression{ op: And(Undefined,Constant(b)), result } => encoding_rule!( 0b01001_110 [u,c] => b, result, data ),
462 Statement::Expression{ op: And(Undefined,Variable(b)), result } => encoding_rule!( 0b01001_111 [u,v] => b, result, data ),
463 Statement::Expression{ op: And(Undefined,Undefined), result } => {
464 Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
465 }
466
467 Statement::Expression{ op: InclusiveOr(Constant(a),Constant(b)), result } => encoding_rule!( 0b01010_000 [c,c] => a, b, result, data ),
469 Statement::Expression{ op: InclusiveOr(Constant(a),Variable(b)), result } => encoding_rule!( 0b01010_001 [c,v] => a, b, result, data ),
470 Statement::Expression{ op: InclusiveOr(Constant(a),Undefined), result } => encoding_rule!( 0b01010_010 [c,u] => a, result, data ),
471 Statement::Expression{ op: InclusiveOr(Variable(a),Constant(b)), result } => encoding_rule!( 0b01010_011 [v,c] => a, b, result, data ),
472 Statement::Expression{ op: InclusiveOr(Variable(a),Variable(b)), result } => encoding_rule!( 0b01010_100 [v,v] => a, b, result, data ),
473 Statement::Expression{ op: InclusiveOr(Variable(a),Undefined), result } => encoding_rule!( 0b01010_101 [v,u] => a, result, data ),
474 Statement::Expression{ op: InclusiveOr(Undefined,Constant(b)), result } => encoding_rule!( 0b01010_110 [u,c] => b, result, data ),
475 Statement::Expression{ op: InclusiveOr(Undefined,Variable(b)), result } => encoding_rule!( 0b01010_111 [u,v] => b, result, data ),
476 Statement::Expression{ op: InclusiveOr(Undefined,Undefined), result } => {
477 Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
478 }
479
480 Statement::Expression{ op: ExclusiveOr(Constant(a),Constant(b)), result } => encoding_rule!( 0b01011_000 [c,c] => a, b, result, data ),
482 Statement::Expression{ op: ExclusiveOr(Constant(a),Variable(b)), result } => encoding_rule!( 0b01011_001 [c,v] => a, b, result, data ),
483 Statement::Expression{ op: ExclusiveOr(Constant(a),Undefined), result } => encoding_rule!( 0b01011_010 [c,u] => a, result, data ),
484 Statement::Expression{ op: ExclusiveOr(Variable(a),Constant(b)), result } => encoding_rule!( 0b01011_011 [v,c] => a, b, result, data ),
485 Statement::Expression{ op: ExclusiveOr(Variable(a),Variable(b)), result } => encoding_rule!( 0b01011_100 [v,v] => a, b, result, data ),
486 Statement::Expression{ op: ExclusiveOr(Variable(a),Undefined), result } => encoding_rule!( 0b01011_101 [v,u] => a, result, data ),
487 Statement::Expression{ op: ExclusiveOr(Undefined,Constant(b)), result } => encoding_rule!( 0b01011_110 [u,c] => b, result, data ),
488 Statement::Expression{ op: ExclusiveOr(Undefined,Variable(b)), result } => encoding_rule!( 0b01011_111 [u,v] => b, result, data ),
489 Statement::Expression{ op: ExclusiveOr(Undefined,Undefined), result } => {
490 Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
491 }
492
493 Statement::Expression{ op: Equal(Constant(a),Constant(b)), result } => encoding_rule!( 0b01100_000 [c,c] => a, b, result, data ),
495 Statement::Expression{ op: Equal(Constant(a),Variable(b)), result } => encoding_rule!( 0b01100_001 [c,v] => a, b, result, data ),
496 Statement::Expression{ op: Equal(Constant(a),Undefined), result } => encoding_rule!( 0b01100_010 [c,u] => a, result, data ),
497 Statement::Expression{ op: Equal(Variable(a),Constant(b)), result } => encoding_rule!( 0b01100_011 [v,c] => a, b, result, data ),
498 Statement::Expression{ op: Equal(Variable(a),Variable(b)), result } => encoding_rule!( 0b01100_100 [v,v] => a, b, result, data ),
499 Statement::Expression{ op: Equal(Variable(a),Undefined), result } => encoding_rule!( 0b01100_101 [v,u] => a, result, data ),
500 Statement::Expression{ op: Equal(Undefined,Constant(b)), result } => encoding_rule!( 0b01100_110 [u,c] => b, result, data ),
501 Statement::Expression{ op: Equal(Undefined,Variable(b)), result } => encoding_rule!( 0b01100_111 [u,v] => b, result, data ),
502 Statement::Expression{ op: Equal(Undefined,Undefined), result } => {
503 Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
504 }
505
506 Statement::Expression{ op: LessOrEqualUnsigned(Constant(a),Constant(b)), result } => encoding_rule!( 0b01101_000 [c,c] => a, b, result, data ),
508 Statement::Expression{ op: LessOrEqualUnsigned(Constant(a),Variable(b)), result } => encoding_rule!( 0b01101_001 [c,v] => a, b, result, data ),
509 Statement::Expression{ op: LessOrEqualUnsigned(Constant(a),Undefined), result } => encoding_rule!( 0b01101_010 [c,u] => a, result, data ),
510 Statement::Expression{ op: LessOrEqualUnsigned(Variable(a),Constant(b)), result } => encoding_rule!( 0b01101_011 [v,c] => a, b, result, data ),
511 Statement::Expression{ op: LessOrEqualUnsigned(Variable(a),Variable(b)), result } => encoding_rule!( 0b01101_100 [v,v] => a, b, result, data ),
512 Statement::Expression{ op: LessOrEqualUnsigned(Variable(a),Undefined), result } => encoding_rule!( 0b01101_101 [v,u] => a, result, data ),
513 Statement::Expression{ op: LessOrEqualUnsigned(Undefined,Constant(b)), result } => encoding_rule!( 0b01101_110 [u,c] => b, result, data ),
514 Statement::Expression{ op: LessOrEqualUnsigned(Undefined,Variable(b)), result } => encoding_rule!( 0b01101_111 [u,v] => b, result, data ),
515 Statement::Expression{ op: LessOrEqualUnsigned(Undefined,Undefined), result } => {
516 Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
517 }
518
519 Statement::Expression{ op: LessOrEqualSigned(Constant(a),Constant(b)), result } => encoding_rule!( 0b01110_000 [c,c] => a, b, result, data ),
521 Statement::Expression{ op: LessOrEqualSigned(Constant(a),Variable(b)), result } => encoding_rule!( 0b01110_001 [c,v] => a, b, result, data ),
522 Statement::Expression{ op: LessOrEqualSigned(Constant(a),Undefined), result } => encoding_rule!( 0b01110_010 [c,u] => a, result, data ),
523 Statement::Expression{ op: LessOrEqualSigned(Variable(a),Constant(b)), result } => encoding_rule!( 0b01110_011 [v,c] => a, b, result, data ),
524 Statement::Expression{ op: LessOrEqualSigned(Variable(a),Variable(b)), result } => encoding_rule!( 0b01110_100 [v,v] => a, b, result, data ),
525 Statement::Expression{ op: LessOrEqualSigned(Variable(a),Undefined), result } => encoding_rule!( 0b01110_101 [v,u] => a, result, data ),
526 Statement::Expression{ op: LessOrEqualSigned(Undefined,Constant(b)), result } => encoding_rule!( 0b01110_110 [u,c] => b, result, data ),
527 Statement::Expression{ op: LessOrEqualSigned(Undefined,Variable(b)), result } => encoding_rule!( 0b01110_111 [u,v] => b, result, data ),
528 Statement::Expression{ op: LessOrEqualSigned(Undefined,Undefined), result } => {
529 Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
530 }
531
532 Statement::Expression{ op: LessUnsigned(Constant(a),Constant(b)), result } => encoding_rule!( 0b01111_000 [c,c] => a, b, result, data ),
534 Statement::Expression{ op: LessUnsigned(Constant(a),Variable(b)), result } => encoding_rule!( 0b01111_001 [c,v] => a, b, result, data ),
535 Statement::Expression{ op: LessUnsigned(Constant(a),Undefined), result } => encoding_rule!( 0b01111_010 [c,u] => a, result, data ),
536 Statement::Expression{ op: LessUnsigned(Variable(a),Constant(b)), result } => encoding_rule!( 0b01111_011 [v,c] => a, b, result, data ),
537 Statement::Expression{ op: LessUnsigned(Variable(a),Variable(b)), result } => encoding_rule!( 0b01111_100 [v,v] => a, b, result, data ),
538 Statement::Expression{ op: LessUnsigned(Variable(a),Undefined), result } => encoding_rule!( 0b01111_101 [v,u] => a, result, data ),
539 Statement::Expression{ op: LessUnsigned(Undefined,Constant(b)), result } => encoding_rule!( 0b01111_110 [u,c] => b, result, data ),
540 Statement::Expression{ op: LessUnsigned(Undefined,Variable(b)), result } => encoding_rule!( 0b01111_111 [u,v] => b, result, data ),
541 Statement::Expression{ op: LessUnsigned(Undefined,Undefined), result } => {
542 Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
543 }
544
545 Statement::Expression{ op: LessSigned(Constant(a),Constant(b)), result } => encoding_rule!( 0b10000_000 [c,c] => a, b, result, data ),
547 Statement::Expression{ op: LessSigned(Constant(a),Variable(b)), result } => encoding_rule!( 0b10000_001 [c,v] => a, b, result, data ),
548 Statement::Expression{ op: LessSigned(Constant(a),Undefined), result } => encoding_rule!( 0b10000_010 [c,u] => a, result, data ),
549 Statement::Expression{ op: LessSigned(Variable(a),Constant(b)), result } => encoding_rule!( 0b10000_011 [v,c] => a, b, result, data ),
550 Statement::Expression{ op: LessSigned(Variable(a),Variable(b)), result } => encoding_rule!( 0b10000_100 [v,v] => a, b, result, data ),
551 Statement::Expression{ op: LessSigned(Variable(a),Undefined), result } => encoding_rule!( 0b10000_101 [v,u] => a, result, data ),
552 Statement::Expression{ op: LessSigned(Undefined,Constant(b)), result } => encoding_rule!( 0b10000_110 [u,c] => b, result, data ),
553 Statement::Expression{ op: LessSigned(Undefined,Variable(b)), result } => encoding_rule!( 0b10000_111 [u,v] => b, result, data ),
554 Statement::Expression{ op: LessSigned(Undefined,Undefined), result } => {
555 Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
556 }
557
558 Statement::Expression{ op: ZeroExtend(sz,Constant(a)), result } => {
560 data.write(&[0b10001000])?;
561 leb128::write::unsigned(data,sz as u64)?;
562 Self::encode_constant(a,data)?;
563 Self::encode_variable(result,data)?;
564 }
565 Statement::Expression{ op: ZeroExtend(sz,Variable(a)), result } => {
566 data.write(&[0b10001001])?;
567 leb128::write::unsigned(data,sz as u64)?;
568 Self::encode_variable(a,data)?;
569 Self::encode_variable(result,data)?;
570 }
571 Statement::Expression{ op: ZeroExtend(_,Undefined), result } => {
572 Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
573 }
574
575 Statement::Expression{ op: SignExtend(sz,Constant(a)), result } => {
577 data.write(&[0b10001010])?;
578 leb128::write::unsigned(data,sz as u64)?;
579 Self::encode_constant(a,data)?;
580 Self::encode_variable(result,data)?;
581 }
582 Statement::Expression{ op: SignExtend(sz,Variable(a)), result } => {
583 data.write(&[0b10001011])?;
584 leb128::write::unsigned(data,sz as u64)?;
585 Self::encode_variable(a,data)?;
586 Self::encode_variable(result,data)?;
587 }
588 Statement::Expression{ op: SignExtend(_,Undefined), result } => {
589 Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
590 }
591
592 Statement::Expression{ op: Move(Constant(a)), result } => {
594 data.write(&[0b10001100])?;
595 Self::encode_constant(a,data)?;
596 Self::encode_variable(result,data)?;
597 }
598 Statement::Expression{ op: Move(Variable(a)), result } => {
599 data.write(&[0b10001101])?;
600 Self::encode_variable(a,data)?;
601 Self::encode_variable(result,data)?;
602 }
603
604 Statement::Expression{ op: Move(Undefined), result } => {
606 data.write(&[0b10001110])?;
607 Self::encode_variable(result,data)?;
608 }
609
610 Statement::Expression{ op: Initialize(name,sz), result } => {
612 data.write(&[0b10001111])?;
613 leb128::write::unsigned(data,name.index() as u64)?;
614 leb128::write::unsigned(data,sz as u64)?;
615 Self::encode_variable(result,data)?;
616 }
617
618 Statement::Expression{ op: Select(off,sz,Constant(src)), result } => {
620 data.write(&[0b10010000])?;
621 leb128::write::unsigned(data,off as u64)?;
622 leb128::write::unsigned(data,sz as u64)?;
623 Self::encode_constant(src,data)?;
624 Self::encode_variable(result,data)?;
625 }
626 Statement::Expression{ op: Select(off,sz,Variable(src)), result } => {
627 data.write(&[0b10010001])?;
628 leb128::write::unsigned(data,off as u64)?;
629 leb128::write::unsigned(data,sz as u64)?;
630 Self::encode_variable(src,data)?;
631 Self::encode_variable(result,data)?;
632 }
633 Statement::Expression{ op: Select(_,_,Undefined), result } => {
634 Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
635 }
636
637 Statement::Expression{ op: Load(segment,Endianess::Little,bytes,Constant(addr)), result } => {
639 data.write(&[0b10010100])?;
640 Self::encode_segment(segment,data)?;
641 leb128::write::unsigned(data,bytes as u64)?;
642 Self::encode_constant(addr,data)?;
643 Self::encode_variable(result,data)?;
644 }
645 Statement::Expression{ op: Load(segment,Endianess::Big,bytes,Constant(addr)), result } => {
646 data.write(&[0b10010110])?;
647 Self::encode_segment(segment,data)?;
648 leb128::write::unsigned(data,bytes as u64)?;
649 Self::encode_constant(addr,data)?;
650 Self::encode_variable(result,data)?;
651 }
652 Statement::Expression{ op: Load(segment,Endianess::Little,bytes,Variable(addr)), result } => {
653 data.write(&[0b10010101])?;
654 Self::encode_segment(segment,data)?;
655 leb128::write::unsigned(data,bytes as u64)?;
656 Self::encode_variable(addr,data)?;
657 Self::encode_variable(result,data)?;
658 }
659 Statement::Expression{ op: Load(segment,Endianess::Big,bytes,Variable(addr)), result } => {
660 data.write(&[0b10010111])?;
661 Self::encode_segment(segment,data)?;
662 leb128::write::unsigned(data,bytes as u64)?;
663 Self::encode_variable(addr,data)?;
664 Self::encode_variable(result,data)?;
665 }
666
667 Statement::Expression{ op: Phi(Variable(a),Variable(b),Undefined), result } |
669 Statement::Expression{ op: Phi(Variable(a),Undefined,Variable(b)), result } |
670 Statement::Expression{ op: Phi(Undefined,Variable(a),Variable(b)), result } => {
671 data.write(&[0b10011000])?;
672 Self::encode_variable(a,data)?;
673 Self::encode_variable(b,data)?;
674 Self::encode_variable(result,data)?;
675 }
676
677 Statement::Expression{ op: Phi(Variable(a),Variable(b),Variable(c)), result } => {
679 data.write(&[0b10011001])?;
680 Self::encode_variable(a,data)?;
681 Self::encode_variable(b,data)?;
682 Self::encode_variable(c,data)?;
683 Self::encode_variable(result,data)?;
684 }
685
686 Statement::Flow{ op: FlowOperation::ExternalCall{ external: name } } => {
688 data.write(&[0b10011010])?;
689 leb128::write::unsigned(data,name.index() as u64)?;
690 }
691
692 Statement::Flow{ op: FlowOperation::Call{ function: uuid } } => {
694 data.write(&[0b10011011])?;
695 Self::encode_uuid(uuid,data)?;
696 }
697
698 Statement::Flow{ op: FlowOperation::IndirectCall{ target: tgt } } => {
700 data.write(&[0b10011101])?;
701 Self::encode_variable(tgt,data)?;
702 }
703
704 Statement::Expression{ op: Phi(Undefined,Undefined,Undefined), result } => {
706 data.write(&[0b10011111])?;
707 Self::encode_variable(result,data)?;
708 }
709
710 Statement::Memory{ op: MemoryOperation::Store{ segment, bytes, endianess, address: Constant(addr), value: Constant(value) }, result } => {
712 data.write(&[0b10100000 | if endianess == Endianess::Little { 0 } else { 0b1000 }])?;
713 Self::encode_segment(segment,data)?;
714 leb128::write::unsigned(data,bytes as u64)?;
715 Self::encode_constant(addr,data)?;
716 Self::encode_constant(value,data)?;
717 Self::encode_segment(result,data)?;
718 }
719 Statement::Memory{ op: MemoryOperation::Store{ segment, bytes, endianess, address: Constant(addr), value: Variable(value) }, result } => {
720 data.write(&[0b10100001 | if endianess == Endianess::Little { 0 } else { 0b1000 }])?;
721 Self::encode_segment(segment,data)?;
722 leb128::write::unsigned(data,bytes as u64)?;
723 Self::encode_constant(addr,data)?;
724 Self::encode_variable(value,data)?;
725 Self::encode_segment(result,data)?;
726 }
727 Statement::Memory{ op: MemoryOperation::Store{ segment, bytes, endianess, address: Constant(addr), value: Undefined }, result } => {
728 data.write(&[0b10100010 | if endianess == Endianess::Little { 0 } else { 0b1000 }])?;
729 Self::encode_segment(segment,data)?;
730 leb128::write::unsigned(data,bytes as u64)?;
731 Self::encode_constant(addr,data)?;
732 Self::encode_segment(result,data)?;
733 }
734 Statement::Memory{ op: MemoryOperation::Store{ segment, bytes, endianess, address: Variable(addr), value: Constant(value) }, result } => {
735 data.write(&[0b10100011 | if endianess == Endianess::Little { 0 } else { 0b1000 }])?;
736 Self::encode_segment(segment,data)?;
737 leb128::write::unsigned(data,bytes as u64)?;
738 Self::encode_variable(addr,data)?;
739 Self::encode_constant(value,data)?;
740 Self::encode_segment(result,data)?;
741 }
742 Statement::Memory{ op: MemoryOperation::Store{ segment, bytes, endianess, address: Variable(addr), value: Variable(value) }, result } => {
743 data.write(&[0b10100100 | if endianess == Endianess::Little { 0 } else { 0b1000 }])?;
744 Self::encode_segment(segment,data)?;
745 leb128::write::unsigned(data,bytes as u64)?;
746 Self::encode_variable(addr,data)?;
747 Self::encode_variable(value,data)?;
748 Self::encode_segment(result,data)?;
749 }
750 Statement::Memory{ op: MemoryOperation::Store{ segment, bytes, endianess, address: Variable(addr), value: Undefined }, result } => {
751 data.write(&[0b10100101 | if endianess == Endianess::Little { 0 } else { 0b1000 }])?;
752 Self::encode_segment(segment,data)?;
753 leb128::write::unsigned(data,bytes as u64)?;
754 Self::encode_variable(addr,data)?;
755 Self::encode_segment(result,data)?;
756 }
757 Statement::Memory{ op: MemoryOperation::Store{ segment, bytes, endianess, address: Undefined, value: Constant(value) }, result } => {
758 data.write(&[0b10100110 | if endianess == Endianess::Little { 0 } else { 0b1000 }])?;
759 Self::encode_segment(segment,data)?;
760 leb128::write::unsigned(data,bytes as u64)?;
761 Self::encode_constant(value,data)?;
762 Self::encode_segment(result,data)?;
763 }
764 Statement::Memory{ op: MemoryOperation::Store{ segment, bytes, endianess, address: Undefined, value: Variable(value) }, result } => {
765 data.write(&[0b10100111 | if endianess == Endianess::Little { 0 } else { 0b1000 }])?;
766 Self::encode_segment(segment,data)?;
767 leb128::write::unsigned(data,bytes as u64)?;
768 Self::encode_variable(value,data)?;
769 Self::encode_segment(result,data)?;
770 }
771 Statement::Memory{ op: MemoryOperation::Store{ address: Undefined, value: Undefined,.. },.. } => { }
772
773 Statement::Flow{ op: FlowOperation::Return } => {
775 data.write(&[0b10110000])?;
776 }
777
778 Statement::Expression{ op: Load(segment,endianess,bytes,Undefined), result } => {
780 data.write(&[0b1011_0010 | if endianess == Endianess::Little { 0 } else { 0b1 }])?;
781 Self::encode_segment(segment,data)?;
782 leb128::write::unsigned(data,bytes as u64)?;
783 Self::encode_variable(result,data)?;
784 }
785
786 Statement::Expression{ op: Phi(Variable(a),Undefined,Undefined), result } => {
788 data.write(&[0b10110100])?;
789 Self::encode_variable(a,data)?;
790 Self::encode_variable(result,data)?;
791 }
792
793 Statement::Expression{ op: Phi(_,_,_),.. } => {
794 return Err(format!("Internal error: invalid Phi expression {:?}",stmt).into());
795 }
796
797 Statement::Memory{ op: MemoryOperation::MemoryPhi(None,None,None), result } => {
799 data.write(&[0b10110101])?;
800 Self::encode_segment(result,data)?;
801 data.write(&[0,0,0])?;
802 }
803
804 Statement::Memory{ op: MemoryOperation::MemoryPhi(Some(a),None,None), result } |
806 Statement::Memory{ op: MemoryOperation::MemoryPhi(None,Some(a),None), result } |
807 Statement::Memory{ op: MemoryOperation::MemoryPhi(None,None,Some(a)), result } => {
808 data.write(&[0b10110110])?;
809 Self::encode_segment(a,data)?;
810 Self::encode_segment(result,data)?;
811 data.write(&[0,0])?;
812 }
813
814 Statement::Memory{ op: MemoryOperation::MemoryPhi(Some(a),Some(b),None), result } |
816 Statement::Memory{ op: MemoryOperation::MemoryPhi(Some(a),None,Some(b)), result } |
817 Statement::Memory{ op: MemoryOperation::MemoryPhi(None,Some(a),Some(b)), result } => {
818 data.write(&[0b10110111])?;
819 Self::encode_segment(a,data)?;
820 Self::encode_segment(b,data)?;
821 Self::encode_segment(result,data)?;
822 data.write(&[0])?;
823 }
824
825 Statement::Memory{ op: MemoryOperation::MemoryPhi(Some(a),Some(b),Some(c)), result } => {
827 data.write(&[0b10111000])?;
828 Self::encode_segment(a,data)?;
829 Self::encode_segment(b,data)?;
830 Self::encode_segment(c,data)?;
831 Self::encode_segment(result,data)?;
832 }
833
834 Statement::Memory{ op: MemoryOperation::Allocate{ base }, result } => {
836 data.write(&[0b10111001])?;
837 leb128::write::unsigned(data,base.index() as u64)?;
838 Self::encode_segment(result,data)?;
839 }
840
841 Statement::Expression{ op: Assume(constr,a), result } => {
843 let code = match (&constr,&a) {
844 (&Constraint::Empty{ .. },&Value::Variable(..)) => 0b000,
845 (&Constraint::Unsigned{ .. },&Value::Variable(..)) => 0b001,
846 (&Constraint::Signed{ .. },&Value::Variable(..)) => 0b010,
847 (&Constraint::Full{ .. },&Value::Variable(..)) => 0b011,
848 (&Constraint::Empty{ .. },_) => 0b100,
849 (&Constraint::Unsigned{ .. },_) => 0b101,
850 (&Constraint::Signed{ .. },_) => 0b110,
851 (&Constraint::Full{ .. },_) => 0b111,
852 };
853
854 data.write(&[0b1100_0000 | code])?;
855 Self::encode_constraint(constr,data)?;
856 if let Value::Variable(var) = a {
857 Self::encode_variable(var,data)?;
858 }
859 Self::encode_variable(result,data)?;
860 }
861 }
862
863 Ok(())
864 }
865
866 fn encode_constant<W: Write>(c: Constant, data: &mut W) -> Result<()> {
868 let Constant{ value, bits } = c;
869 leb128::write::unsigned(data,bits as u64)?;
870 leb128::write::unsigned(data,value)?;
871 Ok(())
872 }
873
874 fn encode_variable<W: Write>(c: Variable, data: &mut W) -> Result<()> {
876 let Variable{ name, bits } = c;
877 leb128::write::unsigned(data,name.index() as u64)?;
878 leb128::write::unsigned(data,bits as u64)?;
879 Ok(())
880 }
881
882 fn encode_segment<W: Write>(c: Segment, data: &mut W) -> Result<()> {
884 let Segment{ name } = c;
885 leb128::write::unsigned(data,name.index() as u64)?;
886 Ok(())
887 }
888
889 fn encode_constraint<W: Write>(c: Constraint, data: &mut W) -> Result<()> {
890 match c {
891 Constraint::Empty{ bits } => {
892 leb128::write::unsigned(data,bits as u64)?;
893 }
894 Constraint::Unsigned{ from, to, bits } => {
895 leb128::write::unsigned(data,bits as u64)?;
896 leb128::write::unsigned(data,from)?;
897 leb128::write::unsigned(data,to)?;
898 }
899 Constraint::Signed{ from, to, bits } => {
900 leb128::write::unsigned(data,bits as u64)?;
901 leb128::write::signed(data,from)?;
902 leb128::write::signed(data,to)?;
903 }
904 Constraint::Full{ bits } => {
905 leb128::write::unsigned(data,bits as u64)?;
906 }
907 }
908
909 Ok(())
910 }
911
912 fn encode_uuid<W: Write>(uu: UUID, data: &mut W) -> Result<()> {
913 let (sch, hi, lo) = match uu {
914 UUID::Name{ name, scope } => (0, name, scope),
915 UUID::Number{ value1, value2 } => (1, value1, value2),
916 UUID::Derived{ timestamp, origin } => (2, timestamp, origin),
917 UUID::Event{ timestamp, origin } => (3, timestamp, origin),
918 };
919
920 data.write(&[sch])?;
921 leb128::write::unsigned(data,hi)?;
922 leb128::write::unsigned(data,lo)?;
923
924 Ok(())
925 }
926
927 fn decode_statement<R: Read>(&self, data: &mut R) -> Result<Statement> {
928 let mut opcode = [0u8; 1];
929 data.read_exact(&mut opcode)?;
930
931 match opcode[0] {
932 0b00000_000...0b00001_000 => {
933 let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
934 let res = self.decode_variable(data)?;
935 let stmt = Statement::Expression{ op: Operation::Add(a,b), result: res };
936
937 Ok(stmt)
938 }
939 0b00001_000...0b00010_000 => {
940 let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
941 let res = self.decode_variable(data)?;
942 let stmt = Statement::Expression{ op: Operation::Subtract(a,b), result: res };
943
944 Ok(stmt)
945 }
946 0b00010_000...0b00011_000 => {
947 let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
948 let res = self.decode_variable(data)?;
949 let stmt = Statement::Expression{ op: Operation::Multiply(a,b), result: res };
950
951 Ok(stmt)
952 }
953 0b00011_000...0b00100_000 => {
954 let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
955 let res = self.decode_variable(data)?;
956 let stmt = Statement::Expression{ op: Operation::DivideUnsigned(a,b), result: res };
957
958 Ok(stmt)
959 }
960 0b00100_000...0b00101_000 => {
961 let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
962 let res = self.decode_variable(data)?;
963 let stmt = Statement::Expression{ op: Operation::DivideSigned(a,b), result: res };
964
965 Ok(stmt)
966 }
967 0b00101_000...0b00110_000 => {
968 let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
969 let res = self.decode_variable(data)?;
970 let stmt = Statement::Expression{ op: Operation::ShiftLeft(a,b), result: res };
971
972 Ok(stmt)
973 }
974 0b00110_000...0b00111_000 => {
975 let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
976 let res = self.decode_variable(data)?;
977 let stmt = Statement::Expression{ op: Operation::ShiftRightUnsigned(a,b), result: res };
978
979 Ok(stmt)
980 }
981 0b00111_000...0b01000_000 => {
982 let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
983 let res = self.decode_variable(data)?;
984 let stmt = Statement::Expression{ op: Operation::ShiftRightSigned(a,b), result: res };
985
986 Ok(stmt)
987 }
988 0b01000_000...0b01001_000 => {
989 let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
990 let res = self.decode_variable(data)?;
991 let stmt = Statement::Expression{ op: Operation::Modulo(a,b), result: res };
992
993 Ok(stmt)
994 }
995 0b01001_000...0b01010_000 => {
996 let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
997 let res = self.decode_variable(data)?;
998 let stmt = Statement::Expression{ op: Operation::And(a,b), result: res };
999
1000 Ok(stmt)
1001 }
1002 0b01010_000...0b01011_000 => {
1003 let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
1004 let res = self.decode_variable(data)?;
1005 let stmt = Statement::Expression{ op: Operation::InclusiveOr(a,b), result: res };
1006
1007 Ok(stmt)
1008 }
1009 0b01011_000...0b01100_000 => {
1010 let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
1011 let res = self.decode_variable(data)?;
1012 let stmt = Statement::Expression{ op: Operation::ExclusiveOr(a,b), result: res };
1013
1014 Ok(stmt)
1015 }
1016 0b01100_000...0b01101_000 => {
1017 let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
1018 let res = self.decode_variable(data)?;
1019 let stmt = Statement::Expression{ op: Operation::Equal(a,b), result: res };
1020
1021 Ok(stmt)
1022 }
1023 0b01101_000...0b01110_000 => {
1024 let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
1025 let res = self.decode_variable(data)?;
1026 let stmt = Statement::Expression{ op: Operation::LessOrEqualUnsigned(a,b), result: res };
1027
1028 Ok(stmt)
1029 }
1030 0b01110_000...0b01111_000 => {
1031 let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
1032 let res = self.decode_variable(data)?;
1033 let stmt = Statement::Expression{ op: Operation::LessOrEqualSigned(a,b), result: res };
1034
1035 Ok(stmt)
1036 }
1037 0b01111_000...0b10000_000 => {
1038 let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
1039 let res = self.decode_variable(data)?;
1040 let stmt = Statement::Expression{ op: Operation::LessUnsigned(a,b), result: res };
1041
1042 Ok(stmt)
1043 }
1044 0b10000_000...0b10000_111 => {
1045 let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
1046 let res = self.decode_variable(data)?;
1047 let stmt = Statement::Expression{ op: Operation::LessSigned(a,b), result: res };
1048
1049 Ok(stmt)
1050 }
1051
1052 0b1000_1000 | 0b1000_1001 => {
1054 let sz = leb128::read::unsigned(data)? as usize;
1055 let a = if opcode[0] & 1 == 0 {
1056 Value::Constant(self.decode_constant(data)?)
1057 } else {
1058 Value::Variable(self.decode_variable(data)?)
1059 };
1060 let res = self.decode_variable(data)?;
1061 let stmt = Statement::Expression{ op: Operation::ZeroExtend(sz,a), result: res };
1062
1063 Ok(stmt)
1064 }
1065
1066 0b1000_1010 | 0b1000_1011 => {
1068 let sz = leb128::read::unsigned(data)? as usize;
1069 let a = if opcode[0] & 1 == 0 {
1070 Value::Constant(self.decode_constant(data)?)
1071 } else {
1072 Value::Variable(self.decode_variable(data)?)
1073 };
1074 let res = self.decode_variable(data)?;
1075 let stmt = Statement::Expression{ op: Operation::SignExtend(sz,a), result: res };
1076
1077 Ok(stmt)
1078 }
1079
1080 0b1000_1100 | 0b1000_1101 => {
1082 let a = if opcode[0] & 1 == 0 {
1083 Value::Constant(self.decode_constant(data)?)
1084 } else {
1085 Value::Variable(self.decode_variable(data)?)
1086 };
1087 let res = self.decode_variable(data)?;
1088 let stmt = Statement::Expression{ op: Operation::Move(a), result: res };
1089
1090 Ok(stmt)
1091 }
1092
1093 0b1000_1110 => {
1095 let res = self.decode_variable(data)?;
1096 let stmt = Statement::Expression{ op: Operation::Move(Value::Undefined), result: res };
1097
1098 Ok(stmt)
1099 }
1100
1101 0b1000_1111 => {
1103 let name = leb128::read::unsigned(data)? as usize;
1104 let sz = leb128::read::unsigned(data)? as usize;
1105 let res = self.decode_variable(data)?;
1106 let stmt = Statement::Expression{
1107 op: Operation::Initialize(StrRef::new(name),sz),
1108 result: res
1109 };
1110
1111 Ok(stmt)
1112 }
1113
1114 0b1001_0000...0b1001_0011 => {
1116 let off = leb128::read::unsigned(data)? as usize;
1117 let sz = leb128::read::unsigned(data)? as usize;
1118 let val = if opcode[0] & 0b1 == 0 {
1119 Value::Constant(self.decode_constant(data)?)
1120 } else {
1121 Value::Variable(self.decode_variable(data)?)
1122 };
1123 let res = self.decode_variable(data)?;
1124 let stmt = Statement::Expression{
1125 op: Operation::Select(off,sz,val),
1126 result: res
1127 };
1128
1129 Ok(stmt)
1130 }
1131
1132 0b1001_0100...0b1001_0111 => {
1134 let seg = self.decode_segment(data)?;
1135 let sz = leb128::read::unsigned(data)? as usize;
1136 let val = if opcode[0] & 0b1 == 0 {
1137 Value::Constant(self.decode_constant(data)?)
1138 } else {
1139 Value::Variable(self.decode_variable(data)?)
1140 };
1141 let endianess = if opcode[0] & 0b10 == 0 {
1142 Endianess::Little
1143 } else {
1144 Endianess::Big
1145 };
1146 let res = self.decode_variable(data)?;
1147 let stmt = Statement::Expression{
1148 op: Operation::Load(seg,endianess,sz,val),
1149 result: res
1150 };
1151
1152 Ok(stmt)
1153 }
1154
1155 0b1001_1000 => {
1157 let a = Value::Variable(self.decode_variable(data)?);
1158 let b = Value::Variable(self.decode_variable(data)?);
1159 let res = self.decode_variable(data)?;
1160 let stmt = Statement::Expression{
1161 op: Operation::Phi(a,b,Value::Undefined),
1162 result: res
1163 };
1164
1165 Ok(stmt)
1166 }
1167
1168 0b1001_1001 => {
1170 let a = Value::Variable(self.decode_variable(data)?);
1171 let b = Value::Variable(self.decode_variable(data)?);
1172 let c = Value::Variable(self.decode_variable(data)?);
1173 let res = self.decode_variable(data)?;
1174 let stmt = Statement::Expression{
1175 op: Operation::Phi(a,b,c),
1176 result: res
1177 };
1178
1179 Ok(stmt)
1180 }
1181
1182 0b1001_1010 => {
1184 let s = leb128::read::unsigned(data)? as usize;
1185 let stmt = Statement::Flow{
1186 op: FlowOperation::ExternalCall{
1187 external: StrRef::new(s)
1188 }
1189 };
1190
1191 Ok(stmt)
1192 }
1193
1194 0b1001_1011 => {
1196 let stmt = Statement::Flow{
1197 op: FlowOperation::Call{
1198 function: self.decode_uuid(data)?
1199 }
1200 };
1201
1202 Ok(stmt)
1203 }
1204
1205 0b1001_1101 => {
1207 let stmt = Statement::Flow{ op:
1208 FlowOperation::IndirectCall{
1209 target: self.decode_variable(data)?
1210 },
1211 };
1212
1213 Ok(stmt)
1214 }
1215
1216 0b1001_1111 => {
1218 let res = self.decode_variable(data)?;
1219 let stmt = Statement::Expression{
1220 op: Operation::Phi(
1221 Value::undef(),
1222 Value::undef(),
1223 Value::undef()),
1224 result: res
1225 };
1226
1227 Ok(stmt)
1228 }
1229
1230 0b1010_0000...0b1010_1111 => {
1232 let seg = self.decode_segment(data)?;
1233 let sz = leb128::read::unsigned(data)? as usize;
1234 let (addr,val) = self.decode_arguments(opcode[0] & 0b111,data)?;
1235 let res = self.decode_segment(data)?;
1236 let endianess = if opcode[0] & 0b1000 == 0 {
1237 Endianess::Little
1238 } else {
1239 Endianess::Big
1240 };
1241 let stmt = Statement::Memory{
1242 op: MemoryOperation::Store{
1243 segment: seg,
1244 bytes: sz,
1245 endianess: endianess,
1246 address: addr,
1247 value: val,
1248 },
1249 result: res,
1250 };
1251
1252 Ok(stmt)
1253 }
1254
1255 0b1011_0000 => {
1257 let stmt = Statement::Flow{ op: FlowOperation::Return };
1258
1259 Ok(stmt)
1260 }
1261
1262 0b1011_0010 | 0b1011_0011 => {
1264 let seg = self.decode_segment(data)?;
1265 let sz = leb128::read::unsigned(data)? as usize;
1266 let endianess = if opcode[0] & 1 == 0 {
1267 Endianess::Little
1268 } else {
1269 Endianess::Big
1270 };
1271 let res = self.decode_variable(data)?;
1272 let stmt = Statement::Expression{
1273 op: Operation::Load(seg,endianess,sz,Value::Undefined),
1274 result: res
1275 };
1276
1277 Ok(stmt)
1278 }
1279
1280 0b10110100 => {
1282 let a = Value::Variable(self.decode_variable(data)?);
1283 let res = self.decode_variable(data)?;
1284 let stmt = Statement::Expression{
1285 op: Operation::Phi(a,Value::undef(),Value::undef()),
1286 result: res
1287 };
1288
1289 Ok(stmt)
1290 }
1291
1292 0b10110101 => {
1294 let res = self.decode_segment(data)?;
1295 let stmt = Statement::Memory{
1296 op: MemoryOperation::MemoryPhi(None,None,None),
1297 result: res
1298 };
1299
1300 data.read(&mut [0;3])?;
1301 Ok(stmt)
1302 }
1303
1304 0b10110110 => {
1306 let a = self.decode_segment(data)?;
1307 let res = self.decode_segment(data)?;
1308 let stmt = Statement::Memory{
1309 op: MemoryOperation::MemoryPhi(Some(a),None,None),
1310 result: res
1311 };
1312
1313 data.read(&mut [0;2])?;
1314 Ok(stmt)
1315 }
1316
1317 0b10110111 => {
1319 let a = self.decode_segment(data)?;
1320 let b = self.decode_segment(data)?;
1321 let res = self.decode_segment(data)?;
1322 let stmt = Statement::Memory{
1323 op: MemoryOperation::MemoryPhi(Some(a),Some(b),None),
1324 result: res
1325 };
1326
1327 data.read(&mut [0;1])?;
1328 Ok(stmt)
1329 }
1330
1331 0b10111000 => {
1333 let a = self.decode_segment(data)?;
1334 let b = self.decode_segment(data)?;
1335 let c = self.decode_segment(data)?;
1336 let res = self.decode_segment(data)?;
1337 let stmt = Statement::Memory{
1338 op: MemoryOperation::MemoryPhi(Some(a),Some(b),Some(c)),
1339 result: res
1340 };
1341
1342 Ok(stmt)
1343 }
1344
1345 0b1011_1001 => {
1347 let name = leb128::read::unsigned(data)? as usize;
1348 let res = self.decode_segment(data)?;
1349 let stmt = Statement::Memory{
1350 op: MemoryOperation::Allocate{ base: StrRef::new(name) },
1351 result: res
1352 };
1353
1354 Ok(stmt)
1355 }
1356
1357 0b1100_0000...0b1100_0111 => {
1359 let constr = self.decode_constraint(opcode[0] & 0b11,data)?;
1360 let a = if opcode[0] & 0b100 == 0 {
1361 Value::Variable(self.decode_variable(data)?)
1362 } else {
1363 Value::Undefined
1364 };
1365 let res = self.decode_variable(data)?;
1366 let stmt = Statement::Expression{ op: Operation::Assume(constr,a), result: res };
1367
1368 Ok(stmt)
1369 }
1370
1371 _ => Err(format!("Internal error: invalid bitcode {:b}",opcode[0]).into()),
1372 }
1373 }
1374
1375 fn decode_arguments<R: Read>(&self, code: u8, data: &mut R) -> Result<(Value,Value)> {
1380 match code {
1381 0b000 => {
1382 let a = self.decode_constant(data)?;
1383 let b = self.decode_constant(data)?;
1384 Ok((Value::Constant(a),Value::Constant(b)))
1385 }
1386 0b001 => {
1387 let a = self.decode_constant(data)?;
1388 let b = self.decode_variable(data)?;
1389 Ok((Value::Constant(a),Value::Variable(b)))
1390 }
1391 0b010 => {
1392 let a = self.decode_constant(data)?;
1393 Ok((Value::Constant(a),Value::Undefined))
1394 }
1395 0b011 => {
1396 let a = self.decode_variable(data)?;
1397 let b = self.decode_constant(data)?;
1398 Ok((Value::Variable(a),Value::Constant(b)))
1399 }
1400 0b100 => {
1401 let a = self.decode_variable(data)?;
1402 let b = self.decode_variable(data)?;
1403 Ok((Value::Variable(a),Value::Variable(b)))
1404 }
1405 0b101 => {
1406 let a = self.decode_variable(data)?;
1407 Ok((Value::Variable(a),Value::Undefined))
1408 }
1409 0b110 => {
1410 let a = self.decode_constant(data)?;
1411 Ok((Value::Undefined,Value::Constant(a)))
1412 }
1413 0b111 => {
1414 let a = self.decode_variable(data)?;
1415 Ok((Value::Undefined,Value::Variable(a)))
1416 }
1417 _ => Err(format!("internal error: impossible argument code {:b}",code).into())
1418 }
1419 }
1420
1421 fn decode_uuid<R: Read>(&self, data: &mut R) -> Result<UUID> {
1422 let mut buf = [0u8; 1];
1423
1424 data.read_exact(&mut buf)?;
1425 let hi = leb128::read::unsigned(data)?;
1426 let lo = leb128::read::unsigned(data)?;
1427
1428 match buf[0] {
1429 0 => Ok(UUID::Name{ name: hi, scope: lo }),
1430 1 => Ok(UUID::Number{ value1: hi, value2: lo }),
1431 2 => Ok(UUID::Derived{ timestamp: hi, origin: lo }),
1432 3 => Ok(UUID::Event{ timestamp: hi, origin: lo }),
1433 _ => Err("unknown UUID scheme".into()),
1434 }
1435 }
1436
1437 fn decode_constant<R: Read>(&self, data: &mut R) -> Result<Constant> {
1439 let bits = leb128::read::unsigned(data)?;
1440 let value = leb128::read::unsigned(data)?;
1441
1442 Ok(Constant{ bits: bits as usize, value: value })
1443 }
1444
1445 fn decode_segment<R: Read>(&self, data: &mut R) -> Result<Segment> {
1447 let name = leb128::read::unsigned(data)?;
1448 let seg = Segment{
1449 name: SegmentRef::new(name as usize),
1450 };
1451
1452 Ok(seg)
1453 }
1454
1455 fn decode_variable<R: Read>(&self, data: &mut R) -> Result<Variable> {
1457 let name = leb128::read::unsigned(data)?;
1458 let bits = leb128::read::unsigned(data)?;
1459 let var = Variable{
1460 name: NameRef::new(name as usize),
1461 bits: bits as usize,
1462 };
1463
1464
1465 Ok(var)
1466 }
1467
1468 fn decode_constraint<R: Read>(&self, code: u8, data: &mut R) -> Result<Constraint> {
1471 let bits = leb128::read::unsigned(data)? as usize;
1472
1473 match code {
1474 0b00 => {
1475 Ok(Constraint::Empty{ bits: bits })
1476 }
1477 0b01 => {
1478 let from = leb128::read::unsigned(data)?;
1479 let to = leb128::read::unsigned(data)?;
1480 let ret = Constraint::Unsigned{
1481 bits: bits,
1482 from: from,
1483 to: to,
1484 };
1485 Ok(ret)
1486 }
1487 0b10 => {
1488 let from = leb128::read::signed(data)?;
1489 let to = leb128::read::signed(data)?;
1490 let ret = Constraint::Signed{
1491 bits: bits,
1492 from: from,
1493 to: to,
1494 };
1495 Ok(ret)
1496 }
1497 0b11 => {
1498 Ok(Constraint::Full{ bits: bits })
1499 }
1500 _ => Err(format!("internal error: impossible constraint code {:b}",code).into())
1501 }
1502 }
1503
1504 pub fn iter<'a>(&'a self) -> BitcodeIter<'a> {
1506 BitcodeIter{
1507 cursor: Cursor::new(&self.data),
1508 bitcode: self,
1509 }
1510 }
1511
1512 pub fn iter_range<'a>(&'a self, rgn: Range<usize>) -> BitcodeIter<'a> {
1514 BitcodeIter{
1515 cursor: Cursor::new(&self.data[rgn]),
1516 bitcode: self,
1517 }
1518 }
1519
1520 pub fn num_bytes(&self) -> usize {
1522 self.data.len()
1523 }
1524}
1525
1526pub struct BitcodeIter<'a> {
1528 cursor: Cursor<&'a [u8]>,
1529 bitcode: &'a Bitcode,
1530}
1531
1532impl<'a> Iterator for BitcodeIter<'a> {
1533 type Item = Statement;
1534
1535 fn next(&mut self) -> Option<Self::Item> {
1536 self.bitcode.decode_statement(&mut self.cursor).ok()
1537 }
1538}
1539
1540#[cfg(test)]
1541mod tests {
1542 use super::*;
1543 use simple_logger;
1544
1545 quickcheck! {
1546 fn round_trip(v: Vec<Statement>) -> bool {
1547 let _ = simple_logger::init();
1548
1549 debug!("in: {:?}",v);
1550 match Bitcode::new(v.clone()) {
1551 Ok(bt) => {
1552 debug!("{:?}",bt);
1553 let w = bt.iter().collect::<Vec<_>>();
1554 debug!("decoded: {:?}",w);
1555 v == w
1556 }
1557 Err(s) => {
1558 debug!("err: {}",s);
1559 false
1560 }
1561 }
1562 }
1563 }
1564
1565 #[test]
1566 fn rewrite_equal_size() {
1567 use Operation::Add;
1568 let s1 = Statement::Expression{
1569 op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1570 result: Variable::new(NameRef::new(0),32).unwrap()
1571 };
1572 let s2 = Statement::Expression{
1573 op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1574 result: Variable::new(NameRef::new(0),32).unwrap()
1575 };
1576 let s3 = Statement::Expression{
1577 op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1578 result: Variable::new(NameRef::new(0),32).unwrap()
1579 };
1580 let mut bitcode = Bitcode::default();
1581
1582 let _ = bitcode.append(vec![s1]).unwrap();
1583 let rgn = bitcode.append(vec![s2]).unwrap();
1584 let _ = bitcode.append(vec![s3]).unwrap();
1585 let mut names = Names::default();
1586 let mut strings = Strings::default();
1587 let mut segments = Segments::default();
1588
1589 let new_rgn = bitcode.rewrite(rgn.clone(),&mut names,&mut strings,&mut segments, |stmt,_,_,_| {
1590 match stmt {
1591 &mut Statement::Expression{ op: Add(Value::Constant(ref mut a),Value::Variable(ref mut b)), ref mut result } => {
1592 *a = Constant::new(43,32).unwrap();
1593 *b = Variable::new(NameRef::new(1),32).unwrap();
1594 *result = Variable::new(NameRef::new(2),32).unwrap();
1595 }
1596 _ => { unreachable!() }
1597 }
1598
1599 Ok(RewriteControl::Continue)
1600 }).unwrap();
1601
1602 assert_eq!(rgn, new_rgn);
1603 for (idx,stmt) in bitcode.iter().enumerate() {
1604 match stmt {
1605 Statement::Expression{ op: Add(Value::Constant(a),Value::Variable(b)), result } => {
1606 if idx == 0 || idx == 2 {
1607 assert_eq!(a, Constant::new(42,32).unwrap());
1608 assert_eq!(b, Variable::new(NameRef::new(0),32).unwrap());
1609 assert_eq!(result, Variable::new(NameRef::new(0),32).unwrap());
1610 } else if idx == 1 {
1611 assert_eq!(a, Constant::new(43,32).unwrap());
1612 assert_eq!(b, Variable::new(NameRef::new(1),32).unwrap());
1613 assert_eq!(result, Variable::new(NameRef::new(2),32).unwrap());
1614 } else {
1615 unreachable!()
1616 }
1617 }
1618 _ => { unreachable!() }
1619 }
1620 }
1621 }
1622
1623 #[test]
1624 fn rewrite_smaller_size() {
1625 use Operation::Add;
1626 let s1 = Statement::Expression{
1627 op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1628 result: Variable::new(NameRef::new(0),32).unwrap()
1629 };
1630 let s2 = Statement::Expression{
1631 op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1632 result: Variable::new(NameRef::new(0),32).unwrap()
1633 };
1634 let s3 = Statement::Expression{
1635 op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1636 result: Variable::new(NameRef::new(0),32).unwrap()
1637 };
1638 let mut bitcode = Bitcode::default();
1639
1640 let _ = bitcode.append(vec![s1]).unwrap();
1641 let rgn = bitcode.append(vec![s2]).unwrap();
1642 let _ = bitcode.append(vec![s3]).unwrap();
1643 let mut names = Names::default();
1644 let mut strings = Strings::default();
1645 let mut segments = Segments::default();
1646
1647 let new_rgn = bitcode.rewrite(rgn.clone(),&mut names, &mut strings,&mut segments, |stmt,_,_,_| {
1648 *stmt = Statement::Flow{ op: FlowOperation::Return };
1649
1650 Ok(RewriteControl::Continue)
1651 }).unwrap();
1652
1653 assert_eq!(rgn.start, new_rgn.start);
1654 for (idx,stmt) in bitcode.iter().enumerate() {
1655 match stmt {
1656 Statement::Expression{ op: Add(Value::Constant(a),Value::Variable(b)), result } => {
1657 assert_eq!(a, Constant::new(42,32).unwrap());
1658 assert_eq!(b, Variable::new(NameRef::new(0),32).unwrap());
1659 assert_eq!(result, Variable::new(NameRef::new(0),32).unwrap());
1660 assert!(idx == 0 || idx == 2);
1661 }
1662 Statement::Flow{ op: FlowOperation::Return } => {
1663 assert_eq!(idx, 1);
1664 }
1665 _ => { unreachable!() }
1666 }
1667 }
1668 }
1669
1670 #[test]
1671 fn rewrite_larger_size() {
1672 use Operation::Add;
1673 let s1 = Statement::Expression{
1674 op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1675 result: Variable::new(NameRef::new(0),32).unwrap()
1676 };
1677 let s2 = Statement::Flow{ op: FlowOperation::Return };
1678 let s3 = Statement::Expression{
1679 op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1680 result: Variable::new(NameRef::new(0),32).unwrap()
1681 };
1682 let mut bitcode = Bitcode::default();
1683
1684 let _ = bitcode.append(vec![s1]).unwrap();
1685 let rgn = bitcode.append(vec![s2]).unwrap();
1686 let _ = bitcode.append(vec![s3]).unwrap();
1687 let mut names = Names::default();
1688 let mut strings = Strings::default();
1689 let mut segments = Segments::default();
1690
1691 let new_rgn = bitcode.rewrite(rgn.clone(),&mut names,&mut strings,&mut segments, |stmt,_,_,_| {
1692 *stmt = Statement::Expression{
1693 op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1694 result: Variable::new(NameRef::new(0),32).unwrap()
1695 };
1696
1697 Ok(RewriteControl::Continue)
1698 }).unwrap();
1699
1700 assert_eq!(rgn.start, new_rgn.start);
1701 assert!(rgn.end < new_rgn.end);
1702 for stmt in bitcode.iter() {
1703 match stmt {
1704 Statement::Expression{ op: Add(Value::Constant(a),Value::Variable(b)), result } => {
1705 assert_eq!(a, Constant::new(42,32).unwrap());
1706 assert_eq!(b, Variable::new(NameRef::new(0),32).unwrap());
1707 assert_eq!(result, Variable::new(NameRef::new(0),32).unwrap());
1708 }
1709 _ => { unreachable!() }
1710 }
1711 }
1712 }
1713
1714 #[test]
1715 fn insert_mid() {
1716 use Operation::Add;
1717 let s1 = Statement::Expression{
1718 op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1719 result: Variable::new(NameRef::new(0),32).unwrap()
1720 };
1721 let s2 = Statement::Expression{
1722 op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1723 result: Variable::new(NameRef::new(0),32).unwrap()
1724 };
1725 let mut bitcode = Bitcode::default();
1726
1727 let _ = bitcode.append(vec![s1]).unwrap();
1728 let rgn = bitcode.append(vec![s2]).unwrap();
1729
1730 let new_rgn = bitcode.insert(rgn.start,vec![Statement::Flow{ op: FlowOperation::Return }]).unwrap();
1731
1732 assert_eq!(rgn.start, new_rgn.start);
1733 for (idx,stmt) in bitcode.iter().enumerate() {
1734 match stmt {
1735 Statement::Expression{ op: Add(Value::Constant(a),Value::Variable(b)), result } => {
1736 assert_eq!(a, Constant::new(42,32).unwrap());
1737 assert_eq!(b, Variable::new(NameRef::new(0),32).unwrap());
1738 assert_eq!(result, Variable::new(NameRef::new(0),32).unwrap());
1739 assert!(idx == 0 || idx == 2);
1740 }
1741 Statement::Flow{ op: FlowOperation::Return } => {
1742 assert_eq!(idx, 1);
1743 }
1744 _ => { unreachable!() }
1745 }
1746 }
1747 }
1748
1749 #[test]
1750 fn insert_start() {
1751 use Operation::Add;
1752 let s1 = Statement::Expression{
1753 op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1754 result: Variable::new(NameRef::new(0),32).unwrap()
1755 };
1756 let mut bitcode = Bitcode::default();
1757 let rgn = bitcode.append(vec![s1]).unwrap();
1758 let new_rgn = bitcode.insert(rgn.start,vec![Statement::Flow{ op: FlowOperation::Return }]).unwrap();
1759
1760 assert_eq!(rgn.start, new_rgn.start);
1761 for (idx,stmt) in bitcode.iter().enumerate() {
1762 match stmt {
1763 Statement::Expression{ op: Add(Value::Constant(a),Value::Variable(b)), result } => {
1764 assert_eq!(a, Constant::new(42,32).unwrap());
1765 assert_eq!(b, Variable::new(NameRef::new(0),32).unwrap());
1766 assert_eq!(result, Variable::new(NameRef::new(0),32).unwrap());
1767 assert_eq!(idx, 1);
1768 }
1769 Statement::Flow{ op: FlowOperation::Return }=> {
1770 assert_eq!(idx, 0);
1771 }
1772 _ => { unreachable!() }
1773 }
1774 }
1775 }
1776
1777 #[test]
1778 fn insert_end() {
1779 use Operation::Add;
1780 let s1 = Statement::Expression{
1781 op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1782 result: Variable::new(NameRef::new(0),32).unwrap()
1783 };
1784 let mut bitcode = Bitcode::default();
1785 let rgn = bitcode.append(vec![s1]).unwrap();
1786 let new_rgn = bitcode.insert(rgn.end,vec![Statement::Flow{ op: FlowOperation::Return }]).unwrap();
1787
1788 assert_eq!(rgn.end, new_rgn.start);
1789 for (idx,stmt) in bitcode.iter().enumerate() {
1790 match stmt {
1791 Statement::Expression{ op: Add(Value::Constant(a),Value::Variable(b)), result } => {
1792 assert_eq!(a, Constant::new(42,32).unwrap());
1793 assert_eq!(b, Variable::new(NameRef::new(0),32).unwrap());
1794 assert_eq!(result, Variable::new(NameRef::new(0),32).unwrap());
1795 assert_eq!(idx, 0);
1796 }
1797 Statement::Flow{ op: FlowOperation::Return } => {
1798 assert_eq!(idx, 1);
1799 }
1800 _ => { unreachable!() }
1801 }
1802 }
1803 }
1804}