1use crate::bytecode_constants::*;
6use crate::interpreter::common::*;
7use crate::interpreter::instruction_decoder::*;
8use num_traits::FromPrimitive;
9use serde::{Deserialize, Serialize};
10use std::collections::HashMap;
11
12pub const NODE_TYPE_HEADER_SZ: usize = 9;
15
16const MINIMUM_BYTECODE_SZ: usize = HEADER_SZ * 3;
19
20const DEBUG_FLAG_SZ: usize = 1;
22
23fn get_symbol_table_and_instruction_debug_bytecode(
27 bytecode: Vec<u8>,
28) -> Result<(HashMap<u32, String>, Vec<u8>, Option<Vec<u8>>), BytecodeError> {
29 if bytecode.len() < MINIMUM_BYTECODE_SZ {
30 return Err(BytecodeError::UnexpectedEnd);
31 }
32
33 let (version, bytecode) = read_and_remove_header(bytecode, BIND_MAGIC_NUM)?;
35 if version != BYTECODE_VERSION {
36 return Err(BytecodeError::InvalidVersion(version));
37 }
38
39 let (debug_flag_byte, bytecode) = read_and_remove_debug_flag(bytecode)?;
41
42 let (symbol_table_sz, mut symbol_table_bytecode) =
45 read_and_remove_header(bytecode, SYMB_MAGIC_NUM)?;
46 if symbol_table_bytecode.len() < symbol_table_sz as usize + HEADER_SZ {
47 return Err(BytecodeError::IncorrectSectionSize);
48 }
49
50 let mut inst_bytecode = symbol_table_bytecode.split_off(symbol_table_sz as usize);
52
53 let inst_bytecode_size = u32::from_le_bytes(get_u32_bytes(&inst_bytecode, 4)?);
55 if inst_bytecode.len() < inst_bytecode_size as usize + HEADER_SZ {
56 return Err(BytecodeError::IncorrectSectionSize);
57 }
58
59 let debug_bytecode = if debug_flag_byte == BYTECODE_ENABLE_DEBUG {
62 let debug_result = inst_bytecode.split_off(inst_bytecode_size as usize + HEADER_SZ);
63 let (debug_sz, debug_result_vec) = read_and_remove_header(debug_result, DEBG_MAGIC_NUM)?;
64 if debug_result_vec.len() != debug_sz as usize {
65 return Err(BytecodeError::IncorrectSectionSize);
66 }
67 Some(debug_result_vec)
68 } else {
69 None
70 };
71
72 Ok((read_symbol_table(symbol_table_bytecode)?, inst_bytecode, debug_bytecode))
73}
74
75fn split_off_node(
78 mut bytecode: Vec<u8>,
79 expect_primary: bool,
80 symbol_table: &HashMap<u32, String>,
81) -> Result<(bool, Node, Vec<u8>), BytecodeError> {
82 let (is_optional, node_id, node_inst_sz) =
84 verify_and_read_node_header(&bytecode, expect_primary)?;
85 if bytecode.len() < NODE_TYPE_HEADER_SZ + node_inst_sz as usize {
86 return Err(BytecodeError::IncorrectNodeSectionSize);
87 }
88
89 if !symbol_table.contains_key(&node_id) {
90 return Err(BytecodeError::MissingNodeIdInSymbolTable);
91 }
92
93 let mut node_instructions = bytecode.split_off(NODE_TYPE_HEADER_SZ);
94 let remaining_bytecode = node_instructions.split_off(node_inst_sz as usize);
95 let decoded_instructions =
96 InstructionDecoder::new(symbol_table, &node_instructions).decode()?;
97 Ok((
98 is_optional,
99 Node {
100 name_id: node_id,
101 instructions: node_instructions,
102 decoded_instructions: decoded_instructions,
103 },
104 remaining_bytecode,
105 ))
106}
107
108#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
109pub enum DecodedRules {
110 Normal(DecodedBindRules),
111 Composite(DecodedCompositeBindRules),
112}
113
114impl DecodedRules {
115 pub fn new(bytecode: Vec<u8>) -> Result<Self, BytecodeError> {
116 let (symbol_table, inst_bytecode, debug_bytecode) =
117 get_symbol_table_and_instruction_debug_bytecode(bytecode)?;
118 let parsed_magic_num = u32::from_be_bytes(get_u32_bytes(&inst_bytecode, 0)?);
119 if parsed_magic_num == COMPOSITE_MAGIC_NUM {
120 return Ok(DecodedRules::Composite(DecodedCompositeBindRules::new(
121 symbol_table,
122 inst_bytecode,
123 decode_debug_bytecode(debug_bytecode)?,
124 )?));
125 }
126 Ok(DecodedRules::Normal(DecodedBindRules::new(
127 symbol_table,
128 inst_bytecode,
129 decode_debug_bytecode(debug_bytecode)?,
130 )?))
131 }
132}
133
134#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
135pub struct DecodedDebugInfo {
136 pub symbol_table: HashMap<u32, String>,
137}
138
139impl DecodedDebugInfo {
140 pub fn new(debug_bytecode: Vec<u8>) -> Result<Self, BytecodeError> {
141 let (debug_sz, debug_sym_bytecode) =
143 read_and_remove_header(debug_bytecode, DBSY_MAGIC_NUM)?;
144 if debug_sym_bytecode.len() != debug_sz as usize {
145 return Err(BytecodeError::IncorrectSectionSize);
146 }
147 let symbol_table = read_symbol_table(debug_sym_bytecode)?;
149
150 Ok(DecodedDebugInfo { symbol_table: symbol_table })
151 }
152}
153
154pub fn decode_debug_bytecode(
156 debug_bytecode: Option<Vec<u8>>,
157) -> Result<Option<DecodedDebugInfo>, BytecodeError> {
158 if debug_bytecode.is_none() {
159 return Ok(None);
160 }
161 let bytecode = debug_bytecode.unwrap();
162 if bytecode.is_empty() {
163 return Ok(None);
164 }
165 return Ok(Some(DecodedDebugInfo::new(bytecode)?));
166}
167
168#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
171pub struct DecodedBindRules {
172 pub symbol_table: HashMap<u32, String>,
173 pub instructions: Vec<u8>,
174 pub decoded_instructions: Vec<DecodedInstruction>,
175 pub debug_info: Option<DecodedDebugInfo>,
176}
177
178impl DecodedBindRules {
179 pub fn new(
180 symbol_table: HashMap<u32, String>,
181 inst_bytecode: Vec<u8>,
182 debug_info: Option<DecodedDebugInfo>,
183 ) -> Result<Self, BytecodeError> {
184 let (inst_sz, inst_bytecode) =
186 read_and_remove_header(inst_bytecode, INSTRUCTION_MAGIC_NUM)?;
187
188 if inst_bytecode.len() != inst_sz as usize {
189 return Err(BytecodeError::IncorrectSectionSize);
190 }
191
192 let decoded_instructions =
193 InstructionDecoder::new(&symbol_table, &inst_bytecode).decode()?;
194
195 Ok(DecodedBindRules {
196 symbol_table: symbol_table,
197 instructions: inst_bytecode,
198 decoded_instructions: decoded_instructions,
199 debug_info: debug_info,
200 })
201 }
202
203 pub fn from_bytecode(bytecode: Vec<u8>) -> Result<Self, BytecodeError> {
204 let (symbol_table, inst_bytecode, debug_bytecode) =
205 get_symbol_table_and_instruction_debug_bytecode(bytecode)?;
206 DecodedBindRules::new(symbol_table, inst_bytecode, decode_debug_bytecode(debug_bytecode)?)
207 }
208}
209
210#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
211pub struct Node {
212 pub name_id: u32,
214 pub instructions: Vec<u8>,
215 pub decoded_instructions: Vec<DecodedInstruction>,
216}
217
218#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
221pub struct DecodedCompositeBindRules {
222 pub symbol_table: HashMap<u32, String>,
223 pub device_name_id: u32,
224 pub primary_node: Node,
225 pub additional_nodes: Vec<Node>,
226 pub optional_nodes: Vec<Node>,
227 pub debug_info: Option<DecodedDebugInfo>,
228}
229
230impl DecodedCompositeBindRules {
231 pub fn new(
232 symbol_table: HashMap<u32, String>,
233 composite_inst_bytecode: Vec<u8>,
234 debug_info: Option<DecodedDebugInfo>,
235 ) -> Result<Self, BytecodeError> {
236 let (composite_inst_sz, mut composite_inst_bytecode) =
239 read_and_remove_header(composite_inst_bytecode, COMPOSITE_MAGIC_NUM)?;
240 if composite_inst_bytecode.len() != composite_inst_sz as usize {
241 return Err(BytecodeError::IncorrectSectionSize);
242 }
243
244 let device_name_id = u32::from_le_bytes(get_u32_bytes(&composite_inst_bytecode, 0)?);
246 if !symbol_table.contains_key(&device_name_id) {
247 return Err(BytecodeError::MissingDeviceNameInSymbolTable);
248 }
249
250 let node_bytecode = composite_inst_bytecode.split_off(4);
252
253 let (_, primary_node, mut node_bytecode) =
255 split_off_node(node_bytecode, true, &symbol_table)?;
256
257 let mut additional_nodes: Vec<Node> = vec![];
259 let mut optional_nodes: Vec<Node> = vec![];
260 while !node_bytecode.is_empty() {
261 let (is_optional, node, remaining) =
262 split_off_node(node_bytecode, false, &symbol_table)?;
263 node_bytecode = remaining;
264 if is_optional {
265 optional_nodes.push(node);
266 } else {
267 additional_nodes.push(node);
268 }
269 }
270
271 Ok(DecodedCompositeBindRules {
272 symbol_table: symbol_table,
273 device_name_id: device_name_id,
274 primary_node: primary_node,
275 additional_nodes: additional_nodes,
276 optional_nodes: optional_nodes,
277 debug_info: debug_info,
278 })
279 }
280
281 pub fn from_bytecode(bytecode: Vec<u8>) -> Result<Self, BytecodeError> {
282 let (symbol_table, inst_bytecode, debug_bytecode) =
283 get_symbol_table_and_instruction_debug_bytecode(bytecode)?;
284 DecodedCompositeBindRules::new(
285 symbol_table,
286 inst_bytecode,
287 decode_debug_bytecode(debug_bytecode)?,
288 )
289 }
290}
291
292fn get_u32_bytes(bytecode: &Vec<u8>, idx: usize) -> Result<[u8; 4], BytecodeError> {
293 if idx + 4 > bytecode.len() {
294 return Err(BytecodeError::UnexpectedEnd);
295 }
296
297 let mut bytes: [u8; 4] = [0; 4];
298 bytes.copy_from_slice(&bytecode[idx..(4 + idx)]);
299 Ok(bytes)
300}
301
302fn read_and_remove_header(
304 mut bytecode: Vec<u8>,
305 magic_num: u32,
306) -> Result<(u32, Vec<u8>), BytecodeError> {
307 let parsed_magic_num = u32::from_be_bytes(get_u32_bytes(&bytecode, 0)?);
308 if parsed_magic_num != magic_num {
309 return Err(BytecodeError::InvalidHeader(magic_num, parsed_magic_num));
310 }
311
312 let val = u32::from_le_bytes(get_u32_bytes(&bytecode, 4)?);
313 Ok((val, bytecode.split_off(HEADER_SZ)))
314}
315
316fn read_and_remove_debug_flag(mut bytecode: Vec<u8>) -> Result<(u8, Vec<u8>), BytecodeError> {
318 let debug_flag_byte = bytecode[0];
319 if debug_flag_byte != BYTECODE_DISABLE_DEBUG && debug_flag_byte != BYTECODE_ENABLE_DEBUG {
320 return Err(BytecodeError::InvalidDebugFlag(debug_flag_byte));
321 }
322 Ok((debug_flag_byte, bytecode.split_off(DEBUG_FLAG_SZ)))
323}
324
325fn verify_and_read_node_header(
327 bytecode: &Vec<u8>,
328 expect_primary: bool,
329) -> Result<(bool, u32, u32), BytecodeError> {
330 if bytecode.len() < NODE_TYPE_HEADER_SZ {
331 return Err(BytecodeError::UnexpectedEnd);
332 }
333
334 let is_optional = match FromPrimitive::from_u8(bytecode[0]) {
335 Some(RawNodeType::Primary) => {
336 if !expect_primary {
337 return Err(BytecodeError::MultiplePrimaryNodes);
338 }
339
340 false
341 }
342 Some(RawNodeType::Additional) => {
343 if expect_primary {
344 return Err(BytecodeError::InvalidPrimaryNode);
345 }
346
347 false
348 }
349 Some(RawNodeType::Optional) => {
350 if expect_primary {
351 return Err(BytecodeError::InvalidPrimaryNode);
352 }
353
354 true
355 }
356 None => {
357 return Err(BytecodeError::InvalidNodeType(bytecode[0]));
358 }
359 };
360
361 let node_id = u32::from_le_bytes(get_u32_bytes(bytecode, 1)?);
362 let inst_sz = u32::from_le_bytes(get_u32_bytes(bytecode, 5)?);
363 Ok((is_optional, node_id, inst_sz))
364}
365
366fn read_string(iter: &mut BytecodeIter) -> Result<String, BytecodeError> {
367 let mut str_bytes = vec![];
368
369 loop {
372 let byte = *next_u8(iter)?;
373 if byte == 0 {
374 break;
375 }
376
377 str_bytes.push(byte);
378 if str_bytes.len() > MAX_STRING_LENGTH {
379 return Err(BytecodeError::InvalidStringLength);
380 }
381 }
382
383 if str_bytes.is_empty() {
384 return Err(BytecodeError::EmptyString);
385 }
386
387 String::from_utf8(str_bytes).map_err(|_| BytecodeError::Utf8ConversionFailure)
388}
389
390fn read_symbol_table(bytecode: Vec<u8>) -> Result<HashMap<u32, String>, BytecodeError> {
391 let mut iter = bytecode.iter();
392
393 let mut symbol_table = HashMap::new();
394 let mut expected_key = SYMB_TBL_START_KEY;
395 while let Some(key) = try_next_u32(&mut iter)? {
396 if key != expected_key {
397 return Err(BytecodeError::InvalidSymbolTableKey(key));
398 }
399
400 let str_val = read_string(&mut iter)?;
403 symbol_table.insert(key, str_val);
404 expected_key += 1;
405 }
406
407 Ok(symbol_table)
408}
409
410#[cfg(test)]
411mod test {
412 use super::*;
413 use crate::compiler::Symbol;
414 use crate::interpreter::test_common::*;
415 use crate::parser::bind_library;
416
417 fn append_section_header(bytecode: &mut Vec<u8>, magic_num: u32, sz: u32) {
418 bytecode.extend_from_slice(&magic_num.to_be_bytes());
419 bytecode.extend_from_slice(&sz.to_le_bytes());
420 }
421
422 fn append_node_header(bytecode: &mut Vec<u8>, node_type: RawNodeType, node_id: u32, sz: u32) {
423 bytecode.push(node_type as u8);
424 bytecode.extend_from_slice(&node_id.to_le_bytes());
425 bytecode.extend_from_slice(&sz.to_le_bytes());
426 }
427
428 #[test]
429 fn test_invalid_header() {
430 let mut bytecode: Vec<u8> = vec![0x41, 0x49, 0x4E, 0x44, 0x02, 0, 0, 0];
432 bytecode.push(BYTECODE_DISABLE_DEBUG);
433 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
434 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
435 assert_eq!(
436 Err(BytecodeError::InvalidHeader(BIND_MAGIC_NUM, 0x41494E44)),
437 DecodedRules::new(bytecode)
438 );
439
440 let mut bytecode: Vec<u8> = vec![0x42, 0x49, 0x4E, 0x44, 0x03, 0, 0, 0];
442 bytecode.push(BYTECODE_DISABLE_DEBUG);
443 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
444 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
445 assert_eq!(Err(BytecodeError::InvalidVersion(3)), DecodedRules::new(bytecode));
446
447 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
449 bytecode.push(BYTECODE_DISABLE_DEBUG);
450 append_section_header(&mut bytecode, 0xAAAAAAAA, 0);
451 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
452 assert_eq!(
453 Err(BytecodeError::InvalidHeader(SYMB_MAGIC_NUM, 0xAAAAAAAA)),
454 DecodedRules::new(bytecode)
455 );
456
457 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
459 bytecode.push(BYTECODE_DISABLE_DEBUG);
460 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
461 append_section_header(&mut bytecode, 0xAAAAAAAA, 0);
462 assert_eq!(
463 Err(BytecodeError::InvalidHeader(INSTRUCTION_MAGIC_NUM, 0xAAAAAAAA)),
464 DecodedRules::new(bytecode)
465 );
466
467 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
469 bytecode.push(BYTECODE_ENABLE_DEBUG);
470 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
471 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
472 append_section_header(&mut bytecode, 0x44454241, 0);
473 assert_eq!(
474 Err(BytecodeError::InvalidHeader(DEBG_MAGIC_NUM, 0x44454241)),
475 DecodedRules::new(bytecode)
476 );
477
478 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
480 bytecode.push(BYTECODE_ENABLE_DEBUG);
481 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
482 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
483 append_section_header(&mut bytecode, DEBG_MAGIC_NUM, 8);
484 append_section_header(&mut bytecode, 0x44454247, 0);
485 assert_eq!(
486 Err(BytecodeError::InvalidHeader(DBSY_MAGIC_NUM, 0x44454247)),
487 DecodedRules::new(bytecode)
488 );
489 }
490
491 #[test]
492 fn test_long_string() {
493 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
494 bytecode.push(BYTECODE_DISABLE_DEBUG);
495
496 let mut long_str: [u8; 275] = [0x41; 275];
497 long_str[274] = 0;
498
499 let symbol_section_sz = long_str.len() + 4;
500 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, symbol_section_sz as u32);
501
502 bytecode.extend_from_slice(&[1, 0, 0, 0]);
503 bytecode.extend_from_slice(&long_str);
504
505 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
506 assert_eq!(Err(BytecodeError::InvalidStringLength), DecodedRules::new(bytecode));
507 }
508
509 #[test]
510 fn test_unexpected_end() {
511 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
512 bytecode.push(BYTECODE_DISABLE_DEBUG);
513 bytecode.extend_from_slice(&SYMB_MAGIC_NUM.to_be_bytes());
514 assert_eq!(Err(BytecodeError::UnexpectedEnd), DecodedRules::new(bytecode));
515 }
516
517 #[test]
518 fn test_string_with_no_zero_terminator() {
519 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
520 bytecode.push(BYTECODE_DISABLE_DEBUG);
521 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 14);
522
523 let invalid_str: [u8; 10] = [0x41; 10];
524 bytecode.extend_from_slice(&[1, 0, 0, 0]);
525 bytecode.extend_from_slice(&invalid_str);
526
527 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
528
529 assert_eq!(Err(BytecodeError::UnexpectedEnd), DecodedRules::new(bytecode));
530 }
531
532 #[test]
533 fn test_duplicate_key() {
534 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
535 bytecode.push(BYTECODE_DISABLE_DEBUG);
536 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 14);
537
538 let str_1: [u8; 3] = [0x41, 0x42, 0];
539 bytecode.extend_from_slice(&[1, 0, 0, 0]);
540 bytecode.extend_from_slice(&str_1);
541
542 let str_2: [u8; 3] = [0x42, 0x43, 0];
543 bytecode.extend_from_slice(&[1, 0, 0, 0]);
544 bytecode.extend_from_slice(&str_2);
545
546 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
547 assert_eq!(Err(BytecodeError::InvalidSymbolTableKey(1)), DecodedRules::new(bytecode));
548 }
549
550 #[test]
551 fn test_invalid_key() {
552 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
553 bytecode.push(BYTECODE_DISABLE_DEBUG);
554 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 15);
555
556 let str_1: [u8; 4] = [0x41, 0x45, 0x60, 0];
557 bytecode.extend_from_slice(&[1, 0, 0, 0]);
558 bytecode.extend_from_slice(&str_1);
559
560 let str_2: [u8; 3] = [0x42, 0x43, 0];
561 bytecode.extend_from_slice(&[5, 0, 0, 0]);
562 bytecode.extend_from_slice(&str_2);
563
564 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
565 assert_eq!(Err(BytecodeError::InvalidSymbolTableKey(5)), DecodedRules::new(bytecode));
566 }
567
568 #[test]
569 fn test_cutoff_symbol_table_key() {
570 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
571 bytecode.push(BYTECODE_DISABLE_DEBUG);
572 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 9);
573
574 let str_1: [u8; 3] = [0x41, 0x42, 0];
575 bytecode.extend_from_slice(&[1, 0, 0, 0]);
576 bytecode.extend_from_slice(&str_1);
577
578 bytecode.extend_from_slice(&[2, 0]);
579 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
580
581 assert_eq!(Err(BytecodeError::UnexpectedEnd), DecodedRules::new(bytecode));
582 }
583
584 #[test]
585 fn test_incorrect_inst_size() {
586 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
587 bytecode.push(BYTECODE_DISABLE_DEBUG);
588 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
589 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
590 bytecode.push(0x30);
591 assert_eq!(Err(BytecodeError::IncorrectSectionSize), DecodedRules::new(bytecode));
592 }
593
594 #[test]
595 fn test_minimum_size_bytecode() {
596 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
597 bytecode.push(BYTECODE_DISABLE_DEBUG);
598 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
599 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
600 assert_eq!(
601 DecodedRules::Normal(DecodedBindRules {
602 symbol_table: HashMap::new(),
603 instructions: vec![],
604 decoded_instructions: vec![],
605 debug_info: None,
606 }),
607 DecodedRules::new(bytecode).unwrap()
608 );
609 }
610
611 #[test]
612 fn test_incorrect_size_symbol_table() {
613 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
614 bytecode.push(BYTECODE_DISABLE_DEBUG);
615 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, u32::MAX);
616 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
617 assert_eq!(Err(BytecodeError::IncorrectSectionSize), DecodedRules::new(bytecode));
618 }
619
620 #[test]
621 fn test_instructions() {
622 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
623 bytecode.push(BYTECODE_DISABLE_DEBUG);
624 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
625
626 let instructions = [0x30, 0x01, 0x01, 0, 0, 0, 0x05, 0x01, 0x10, 0, 0, 0x10];
627 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, instructions.len() as u32);
628 bytecode.extend_from_slice(&instructions);
629 let bind_rules = DecodedBindRules::from_bytecode(bytecode).unwrap();
630 assert_eq!(instructions.to_vec(), bind_rules.instructions);
631 }
632
633 #[test]
634 fn test_enable_debug_flag_empty_debug_info_section() {
635 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
636 bytecode.push(BYTECODE_ENABLE_DEBUG);
637 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
638
639 let instructions = [0x30];
640 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, instructions.len() as u32);
641 bytecode.extend_from_slice(&instructions);
642 append_section_header(&mut bytecode, DEBG_MAGIC_NUM, 0);
643
644 let rules = DecodedBindRules {
645 symbol_table: HashMap::new(),
646 instructions: vec![0x30],
647 decoded_instructions: vec![DecodedInstruction::UnconditionalAbort],
648 debug_info: None,
649 };
650
651 assert_eq!(DecodedRules::Normal(rules), DecodedRules::new(bytecode).unwrap());
652 }
653
654 #[test]
655 fn test_enable_debug_flag_empty_debug_symb_section() {
656 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
657 bytecode.push(BYTECODE_ENABLE_DEBUG);
658 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
659
660 let instructions = [0x30];
661 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, instructions.len() as u32);
662 bytecode.extend_from_slice(&instructions);
663 append_section_header(&mut bytecode, DEBG_MAGIC_NUM, 8);
664 append_section_header(&mut bytecode, DBSY_MAGIC_NUM, 0);
665
666 let rules = DecodedBindRules {
667 symbol_table: HashMap::new(),
668 instructions: vec![0x30],
669 decoded_instructions: vec![DecodedInstruction::UnconditionalAbort],
670 debug_info: Some(DecodedDebugInfo { symbol_table: HashMap::new() }),
671 };
672
673 assert_eq!(DecodedRules::Normal(rules), DecodedRules::new(bytecode).unwrap());
674 }
675
676 #[test]
677 fn test_enable_debug_flag() {
678 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
679 bytecode.push(BYTECODE_ENABLE_DEBUG);
680 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
681
682 let instructions = [0x30];
683 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, instructions.len() as u32);
684 bytecode.extend_from_slice(&instructions);
685
686 append_section_header(&mut bytecode, DEBG_MAGIC_NUM, 0x22);
687 append_section_header(&mut bytecode, DBSY_MAGIC_NUM, 0x1A);
688
689 let str_1: [u8; 22] = [
690 0x66, 0x75, 0x63, 0x68, 0x73, 0x69, 0x61, 0x2e, 0x42, 0x49, 0x4e, 0x44, 0x5f, 0x50,
692 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0,
693 ];
694 bytecode.extend_from_slice(&[1, 0, 0, 0]);
695 bytecode.extend_from_slice(&str_1);
696
697 let mut expected_symbol_table: HashMap<u32, String> = HashMap::new();
698 expected_symbol_table.insert(1, "fuchsia.BIND_PROTOCOL".to_string());
699
700 let rules = DecodedBindRules {
701 symbol_table: HashMap::new(),
702 instructions: vec![0x30],
703 decoded_instructions: vec![DecodedInstruction::UnconditionalAbort],
704 debug_info: Some(DecodedDebugInfo { symbol_table: expected_symbol_table }),
705 };
706
707 assert_eq!(DecodedRules::Normal(rules), DecodedRules::new(bytecode).unwrap());
708 }
709
710 #[test]
711 fn test_missing_debug_flag() {
712 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
713 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
714
715 let instructions = [0x01, 0x01, 0x05, 0, 0, 0, 0x01, 0x16, 0, 0, 0];
716 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, instructions.len() as u32);
717 bytecode.extend_from_slice(&instructions);
718
719 assert_eq!(Err(BytecodeError::InvalidDebugFlag(0x53)), DecodedRules::new(bytecode));
720 }
721
722 #[test]
723 fn test_invalid_debug_flag() {
724 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
725 bytecode.push(0x03);
726 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
727
728 let instructions = [0x01, 0x01, 0x05, 0, 0, 0, 0x01, 0x16, 0, 0, 0];
729 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, instructions.len() as u32);
730 bytecode.extend_from_slice(&instructions);
731
732 assert_eq!(Err(BytecodeError::InvalidDebugFlag(0x03)), DecodedRules::new(bytecode));
733 }
734
735 #[test]
736 fn test_value_key_missing_in_symbols() {
737 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
738 bytecode.push(BYTECODE_DISABLE_DEBUG);
739 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
740
741 let instructions = [0x01, 0x00, 0, 0, 0, 0x05, 0x10, 0, 0, 0, 0];
742 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, instructions.len() as u32);
743 bytecode.extend_from_slice(&instructions);
744
745 assert_eq!(
746 Err(BytecodeError::MissingEntryInSymbolTable(0x05000000)),
747 DecodedRules::new(bytecode)
748 );
749 }
750
751 #[test]
752 fn test_valid_bytecode() {
753 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
754 bytecode.push(BYTECODE_DISABLE_DEBUG);
755 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 18);
756
757 let str_1: [u8; 5] = [0x57, 0x52, 0x45, 0x4E, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
759 bytecode.extend_from_slice(&str_1);
760
761 let str_2: [u8; 5] = [0x44, 0x55, 0x43, 0x4B, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
763 bytecode.extend_from_slice(&str_2);
764
765 let instructions = [
766 0x01, 0x01, 0, 0, 0, 0x05, 0x01, 0x10, 0, 0, 0x10, 0x11, 0x01, 0, 0, 0, 0x01, 0, 0, 0, 0x05, 0x01, 0x10, 0, 0,
768 0, 0x30, 0x20, 0x11, 0x01, 0, 0, 0, 0x00, 0x01, 0, 0, 0, 0x02, 0x02, 0, 0,
771 0, 0x30, 0x20, 0x10, 0x02, 0, 0, 0, 0x30, 0x30, 0x20, ];
775 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, instructions.len() as u32);
776 bytecode.extend_from_slice(&instructions);
777
778 let mut expected_symbol_table: HashMap<u32, String> = HashMap::new();
779 expected_symbol_table.insert(1, "WREN".to_string());
780 expected_symbol_table.insert(2, "DUCK".to_string());
781
782 let expected_decoded_inst = vec![
783 DecodedInstruction::Condition(DecodedCondition {
784 is_equal: true,
785 lhs: Symbol::NumberValue(0x05000000),
786 rhs: Symbol::NumberValue(0x10000010),
787 }),
788 DecodedInstruction::Jump(Some(DecodedCondition {
789 is_equal: true,
790 lhs: Symbol::NumberValue(0x05000000),
791 rhs: Symbol::NumberValue(0x10),
792 })),
793 DecodedInstruction::UnconditionalAbort,
794 DecodedInstruction::Label,
795 DecodedInstruction::Jump(Some(DecodedCondition {
796 is_equal: true,
797 lhs: Symbol::Key("WREN".to_string(), bind_library::ValueType::Str),
798 rhs: Symbol::StringValue("DUCK".to_string()),
799 })),
800 DecodedInstruction::UnconditionalAbort,
801 DecodedInstruction::Label,
802 DecodedInstruction::Jump(None),
803 DecodedInstruction::UnconditionalAbort,
804 DecodedInstruction::UnconditionalAbort,
805 DecodedInstruction::Label,
806 ];
807
808 let rules = DecodedBindRules {
809 symbol_table: expected_symbol_table,
810 instructions: instructions.to_vec(),
811 decoded_instructions: expected_decoded_inst,
812 debug_info: None,
813 };
814 assert_eq!(DecodedRules::Normal(rules), DecodedRules::new(bytecode).unwrap());
815 }
816
817 #[test]
818 fn test_enable_debug_composite() {
819 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
820 bytecode.push(BYTECODE_ENABLE_DEBUG);
821 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 38);
822
823 let device_name: [u8; 5] = [0x49, 0x42, 0x49, 0x53, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
825 bytecode.extend_from_slice(&device_name);
826
827 let primary_node_name: [u8; 5] = [0x52, 0x41, 0x49, 0x4C, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
829 bytecode.extend_from_slice(&primary_node_name);
830
831 let node_name_1: [u8; 5] = [0x43, 0x4F, 0x4F, 0x54, 0]; bytecode.extend_from_slice(&[3, 0, 0, 0]);
833 bytecode.extend_from_slice(&node_name_1);
834
835 let node_name_2: [u8; 7] = [0x50, 0x4C, 0x4F, 0x56, 0x45, 0x52, 0]; bytecode.extend_from_slice(&[4, 0, 0, 0]);
837 bytecode.extend_from_slice(&node_name_2);
838
839 let primary_node_inst = [0x30, 0x01, 0x01, 0, 0, 0, 0x05, 0x01, 0x10, 0, 0x20, 0];
840 let additional_node_inst_1 = [0x02, 0x01, 0, 0, 0, 0x02, 0x01, 0, 0, 0, 0x10];
841 let additional_node_inst_2 = [0x30, 0x30];
842
843 let composite_insts_sz = COMPOSITE_NAME_ID_BYTES
844 + ((NODE_TYPE_HEADER_SZ * 3)
845 + primary_node_inst.len()
846 + additional_node_inst_1.len()
847 + additional_node_inst_2.len()) as u32;
848 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
849
850 bytecode.extend_from_slice(&[1, 0, 0, 0]);
852
853 append_node_header(&mut bytecode, RawNodeType::Primary, 2, primary_node_inst.len() as u32);
855 bytecode.extend_from_slice(&primary_node_inst);
856 append_node_header(
857 &mut bytecode,
858 RawNodeType::Additional,
859 3,
860 additional_node_inst_1.len() as u32,
861 );
862 bytecode.extend_from_slice(&additional_node_inst_1);
863 append_node_header(
864 &mut bytecode,
865 RawNodeType::Additional,
866 4,
867 additional_node_inst_2.len() as u32,
868 );
869 bytecode.extend_from_slice(&additional_node_inst_2);
870
871 let mut expected_symbol_table: HashMap<u32, String> = HashMap::new();
872 expected_symbol_table.insert(1, "IBIS".to_string());
873 expected_symbol_table.insert(2, "RAIL".to_string());
874 expected_symbol_table.insert(3, "COOT".to_string());
875 expected_symbol_table.insert(4, "PLOVER".to_string());
876
877 append_section_header(&mut bytecode, DEBG_MAGIC_NUM, 0x22);
878 append_section_header(&mut bytecode, DBSY_MAGIC_NUM, 0x1A);
879
880 let str_1: [u8; 22] = [
881 0x66, 0x75, 0x63, 0x68, 0x73, 0x69, 0x61, 0x2e, 0x42, 0x49, 0x4e, 0x44, 0x5f, 0x50,
883 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0,
884 ];
885 bytecode.extend_from_slice(&[1, 0, 0, 0]);
886 bytecode.extend_from_slice(&str_1);
887
888 let mut debug_symbol_table: HashMap<u32, String> = HashMap::new();
889 debug_symbol_table.insert(1, "fuchsia.BIND_PROTOCOL".to_string());
890
891 let rules = DecodedCompositeBindRules {
892 symbol_table: expected_symbol_table,
893 device_name_id: 1,
894 primary_node: Node {
895 name_id: 2,
896 instructions: primary_node_inst.to_vec(),
897 decoded_instructions: vec![
898 DecodedInstruction::UnconditionalAbort,
899 DecodedInstruction::Condition(DecodedCondition {
900 is_equal: true,
901 lhs: Symbol::NumberValue(0x5000000),
902 rhs: Symbol::NumberValue(0x200010),
903 }),
904 ],
905 },
906 additional_nodes: vec![
907 Node {
908 name_id: 3,
909 instructions: additional_node_inst_1.to_vec(),
910 decoded_instructions: vec![DecodedInstruction::Condition(DecodedCondition {
911 is_equal: false,
912 lhs: Symbol::NumberValue(0x2000000),
913 rhs: Symbol::NumberValue(0x10000000),
914 })],
915 },
916 Node {
917 name_id: 4,
918 instructions: additional_node_inst_2.to_vec(),
919 decoded_instructions: vec![
920 DecodedInstruction::UnconditionalAbort,
921 DecodedInstruction::UnconditionalAbort,
922 ],
923 },
924 ],
925 optional_nodes: vec![],
926 debug_info: Some(DecodedDebugInfo { symbol_table: debug_symbol_table }),
927 };
928 assert_eq!(DecodedRules::Composite(rules), DecodedRules::new(bytecode).unwrap());
929 }
930
931 #[test]
932 fn test_enable_debug_composite_with_optional() {
933 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
934 bytecode.push(BYTECODE_ENABLE_DEBUG);
935 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 38);
936
937 let device_name: [u8; 5] = [0x49, 0x42, 0x49, 0x53, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
939 bytecode.extend_from_slice(&device_name);
940
941 let primary_node_name: [u8; 5] = [0x52, 0x41, 0x49, 0x4C, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
943 bytecode.extend_from_slice(&primary_node_name);
944
945 let node_name_1: [u8; 5] = [0x43, 0x4F, 0x4F, 0x54, 0]; bytecode.extend_from_slice(&[3, 0, 0, 0]);
947 bytecode.extend_from_slice(&node_name_1);
948
949 let node_name_2: [u8; 7] = [0x50, 0x4C, 0x4F, 0x56, 0x45, 0x52, 0]; bytecode.extend_from_slice(&[4, 0, 0, 0]);
951 bytecode.extend_from_slice(&node_name_2);
952
953 let primary_node_inst = [0x30, 0x01, 0x01, 0, 0, 0, 0x05, 0x01, 0x10, 0, 0x20, 0];
954 let additional_node_inst_1 = [0x02, 0x01, 0, 0, 0, 0x02, 0x01, 0, 0, 0, 0x10];
955 let optional_node_inst_1 = [0x30, 0x30];
956
957 let composite_insts_sz = COMPOSITE_NAME_ID_BYTES
958 + ((NODE_TYPE_HEADER_SZ * 3)
959 + primary_node_inst.len()
960 + additional_node_inst_1.len()
961 + optional_node_inst_1.len()) as u32;
962 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
963
964 bytecode.extend_from_slice(&[1, 0, 0, 0]);
966
967 append_node_header(&mut bytecode, RawNodeType::Primary, 2, primary_node_inst.len() as u32);
969 bytecode.extend_from_slice(&primary_node_inst);
970 append_node_header(
971 &mut bytecode,
972 RawNodeType::Additional,
973 3,
974 additional_node_inst_1.len() as u32,
975 );
976 bytecode.extend_from_slice(&additional_node_inst_1);
977 append_node_header(
978 &mut bytecode,
979 RawNodeType::Optional,
980 4,
981 optional_node_inst_1.len() as u32,
982 );
983 bytecode.extend_from_slice(&optional_node_inst_1);
984
985 let mut expected_symbol_table: HashMap<u32, String> = HashMap::new();
986 expected_symbol_table.insert(1, "IBIS".to_string());
987 expected_symbol_table.insert(2, "RAIL".to_string());
988 expected_symbol_table.insert(3, "COOT".to_string());
989 expected_symbol_table.insert(4, "PLOVER".to_string());
990
991 append_section_header(&mut bytecode, DEBG_MAGIC_NUM, 0x22);
992 append_section_header(&mut bytecode, DBSY_MAGIC_NUM, 0x1A);
993
994 let str_1: [u8; 22] = [
995 0x66, 0x75, 0x63, 0x68, 0x73, 0x69, 0x61, 0x2e, 0x42, 0x49, 0x4e, 0x44, 0x5f, 0x50,
997 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0,
998 ];
999 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1000 bytecode.extend_from_slice(&str_1);
1001
1002 let mut debug_symbol_table: HashMap<u32, String> = HashMap::new();
1003 debug_symbol_table.insert(1, "fuchsia.BIND_PROTOCOL".to_string());
1004
1005 let rules = DecodedCompositeBindRules {
1006 symbol_table: expected_symbol_table,
1007 device_name_id: 1,
1008 primary_node: Node {
1009 name_id: 2,
1010 instructions: primary_node_inst.to_vec(),
1011 decoded_instructions: vec![
1012 DecodedInstruction::UnconditionalAbort,
1013 DecodedInstruction::Condition(DecodedCondition {
1014 is_equal: true,
1015 lhs: Symbol::NumberValue(0x5000000),
1016 rhs: Symbol::NumberValue(0x200010),
1017 }),
1018 ],
1019 },
1020 additional_nodes: vec![Node {
1021 name_id: 3,
1022 instructions: additional_node_inst_1.to_vec(),
1023 decoded_instructions: vec![DecodedInstruction::Condition(DecodedCondition {
1024 is_equal: false,
1025 lhs: Symbol::NumberValue(0x2000000),
1026 rhs: Symbol::NumberValue(0x10000000),
1027 })],
1028 }],
1029 optional_nodes: vec![Node {
1030 name_id: 4,
1031 instructions: optional_node_inst_1.to_vec(),
1032 decoded_instructions: vec![
1033 DecodedInstruction::UnconditionalAbort,
1034 DecodedInstruction::UnconditionalAbort,
1035 ],
1036 }],
1037 debug_info: Some(DecodedDebugInfo { symbol_table: debug_symbol_table }),
1038 };
1039 assert_eq!(DecodedRules::Composite(rules), DecodedRules::new(bytecode).unwrap());
1040 }
1041
1042 #[test]
1043 fn test_valid_composite_bind() {
1044 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1045 bytecode.push(BYTECODE_DISABLE_DEBUG);
1046 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 38);
1047
1048 let device_name: [u8; 5] = [0x49, 0x42, 0x49, 0x53, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1050 bytecode.extend_from_slice(&device_name);
1051
1052 let primary_node_name: [u8; 5] = [0x52, 0x41, 0x49, 0x4C, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1054 bytecode.extend_from_slice(&primary_node_name);
1055
1056 let node_name_1: [u8; 5] = [0x43, 0x4F, 0x4F, 0x54, 0]; bytecode.extend_from_slice(&[3, 0, 0, 0]);
1058 bytecode.extend_from_slice(&node_name_1);
1059
1060 let node_name_2: [u8; 7] = [0x50, 0x4C, 0x4F, 0x56, 0x45, 0x52, 0]; bytecode.extend_from_slice(&[4, 0, 0, 0]);
1062 bytecode.extend_from_slice(&node_name_2);
1063
1064 let primary_node_inst = [0x30, 0x01, 0x01, 0, 0, 0, 0x05, 0x01, 0x10, 0, 0x20, 0];
1065 let additional_node_inst_1 = [0x02, 0x01, 0, 0, 0, 0x02, 0x01, 0, 0, 0, 0x10];
1066 let additional_node_inst_2 = [0x30, 0x30];
1067
1068 let composite_insts_sz = COMPOSITE_NAME_ID_BYTES
1069 + ((NODE_TYPE_HEADER_SZ * 3)
1070 + primary_node_inst.len()
1071 + additional_node_inst_1.len()
1072 + additional_node_inst_2.len()) as u32;
1073 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1074
1075 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1077
1078 append_node_header(&mut bytecode, RawNodeType::Primary, 2, primary_node_inst.len() as u32);
1080 bytecode.extend_from_slice(&primary_node_inst);
1081 append_node_header(
1082 &mut bytecode,
1083 RawNodeType::Additional,
1084 3,
1085 additional_node_inst_1.len() as u32,
1086 );
1087 bytecode.extend_from_slice(&additional_node_inst_1);
1088 append_node_header(
1089 &mut bytecode,
1090 RawNodeType::Additional,
1091 4,
1092 additional_node_inst_2.len() as u32,
1093 );
1094 bytecode.extend_from_slice(&additional_node_inst_2);
1095
1096 let mut expected_symbol_table: HashMap<u32, String> = HashMap::new();
1097 expected_symbol_table.insert(1, "IBIS".to_string());
1098 expected_symbol_table.insert(2, "RAIL".to_string());
1099 expected_symbol_table.insert(3, "COOT".to_string());
1100 expected_symbol_table.insert(4, "PLOVER".to_string());
1101
1102 let rules = DecodedCompositeBindRules {
1103 symbol_table: expected_symbol_table,
1104 device_name_id: 1,
1105 primary_node: Node {
1106 name_id: 2,
1107 instructions: primary_node_inst.to_vec(),
1108 decoded_instructions: vec![
1109 DecodedInstruction::UnconditionalAbort,
1110 DecodedInstruction::Condition(DecodedCondition {
1111 is_equal: true,
1112 lhs: Symbol::NumberValue(0x5000000),
1113 rhs: Symbol::NumberValue(0x200010),
1114 }),
1115 ],
1116 },
1117 additional_nodes: vec![
1118 Node {
1119 name_id: 3,
1120 instructions: additional_node_inst_1.to_vec(),
1121 decoded_instructions: vec![DecodedInstruction::Condition(DecodedCondition {
1122 is_equal: false,
1123 lhs: Symbol::NumberValue(0x2000000),
1124 rhs: Symbol::NumberValue(0x10000000),
1125 })],
1126 },
1127 Node {
1128 name_id: 4,
1129 instructions: additional_node_inst_2.to_vec(),
1130 decoded_instructions: vec![
1131 DecodedInstruction::UnconditionalAbort,
1132 DecodedInstruction::UnconditionalAbort,
1133 ],
1134 },
1135 ],
1136 optional_nodes: vec![],
1137 debug_info: None,
1138 };
1139 assert_eq!(DecodedRules::Composite(rules), DecodedRules::new(bytecode).unwrap());
1140 }
1141
1142 #[test]
1143 fn test_valid_composite_bind_with_optional() {
1144 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1145 bytecode.push(BYTECODE_DISABLE_DEBUG);
1146 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 38);
1147
1148 let device_name: [u8; 5] = [0x49, 0x42, 0x49, 0x53, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1150 bytecode.extend_from_slice(&device_name);
1151
1152 let primary_node_name: [u8; 5] = [0x52, 0x41, 0x49, 0x4C, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1154 bytecode.extend_from_slice(&primary_node_name);
1155
1156 let node_name_1: [u8; 5] = [0x43, 0x4F, 0x4F, 0x54, 0]; bytecode.extend_from_slice(&[3, 0, 0, 0]);
1158 bytecode.extend_from_slice(&node_name_1);
1159
1160 let node_name_2: [u8; 7] = [0x50, 0x4C, 0x4F, 0x56, 0x45, 0x52, 0]; bytecode.extend_from_slice(&[4, 0, 0, 0]);
1162 bytecode.extend_from_slice(&node_name_2);
1163
1164 let primary_node_inst = [0x30, 0x01, 0x01, 0, 0, 0, 0x05, 0x01, 0x10, 0, 0x20, 0];
1165 let additional_node_inst_1 = [0x02, 0x01, 0, 0, 0, 0x02, 0x01, 0, 0, 0, 0x10];
1166 let optional_node_inst_1 = [0x30, 0x30];
1167
1168 let composite_insts_sz = COMPOSITE_NAME_ID_BYTES
1169 + ((NODE_TYPE_HEADER_SZ * 3)
1170 + primary_node_inst.len()
1171 + additional_node_inst_1.len()
1172 + optional_node_inst_1.len()) as u32;
1173 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1174
1175 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1177
1178 append_node_header(&mut bytecode, RawNodeType::Primary, 2, primary_node_inst.len() as u32);
1180 bytecode.extend_from_slice(&primary_node_inst);
1181 append_node_header(
1182 &mut bytecode,
1183 RawNodeType::Additional,
1184 3,
1185 additional_node_inst_1.len() as u32,
1186 );
1187 bytecode.extend_from_slice(&additional_node_inst_1);
1188 append_node_header(
1189 &mut bytecode,
1190 RawNodeType::Optional,
1191 4,
1192 optional_node_inst_1.len() as u32,
1193 );
1194 bytecode.extend_from_slice(&optional_node_inst_1);
1195
1196 let mut expected_symbol_table: HashMap<u32, String> = HashMap::new();
1197 expected_symbol_table.insert(1, "IBIS".to_string());
1198 expected_symbol_table.insert(2, "RAIL".to_string());
1199 expected_symbol_table.insert(3, "COOT".to_string());
1200 expected_symbol_table.insert(4, "PLOVER".to_string());
1201
1202 let rules = DecodedCompositeBindRules {
1203 symbol_table: expected_symbol_table,
1204 device_name_id: 1,
1205 primary_node: Node {
1206 name_id: 2,
1207 instructions: primary_node_inst.to_vec(),
1208 decoded_instructions: vec![
1209 DecodedInstruction::UnconditionalAbort,
1210 DecodedInstruction::Condition(DecodedCondition {
1211 is_equal: true,
1212 lhs: Symbol::NumberValue(0x5000000),
1213 rhs: Symbol::NumberValue(0x200010),
1214 }),
1215 ],
1216 },
1217 additional_nodes: vec![Node {
1218 name_id: 3,
1219 instructions: additional_node_inst_1.to_vec(),
1220 decoded_instructions: vec![DecodedInstruction::Condition(DecodedCondition {
1221 is_equal: false,
1222 lhs: Symbol::NumberValue(0x2000000),
1223 rhs: Symbol::NumberValue(0x10000000),
1224 })],
1225 }],
1226 optional_nodes: vec![Node {
1227 name_id: 4,
1228 instructions: optional_node_inst_1.to_vec(),
1229 decoded_instructions: vec![
1230 DecodedInstruction::UnconditionalAbort,
1231 DecodedInstruction::UnconditionalAbort,
1232 ],
1233 }],
1234 debug_info: None,
1235 };
1236 assert_eq!(DecodedRules::Composite(rules), DecodedRules::new(bytecode).unwrap());
1237 }
1238
1239 #[test]
1240 fn test_primary_node_only() {
1241 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1242 bytecode.push(BYTECODE_DISABLE_DEBUG);
1243 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 18);
1244
1245 let device_name: [u8; 5] = [0x49, 0x42, 0x49, 0x53, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1247 bytecode.extend_from_slice(&device_name);
1248
1249 let primary_node_name: [u8; 5] = [0x43, 0x4F, 0x4F, 0x54, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1251 bytecode.extend_from_slice(&primary_node_name);
1252
1253 let primary_node_inst = [0x30, 0x01, 0x01, 0, 0, 0, 0x05, 0x01, 0x10, 0, 0x20, 0];
1254
1255 let composite_insts_sz =
1256 COMPOSITE_NAME_ID_BYTES + (NODE_TYPE_HEADER_SZ + primary_node_inst.len()) as u32;
1257 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1258
1259 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1261
1262 append_node_header(&mut bytecode, RawNodeType::Primary, 2, primary_node_inst.len() as u32);
1264 bytecode.extend_from_slice(&primary_node_inst);
1265
1266 let mut expected_symbol_table: HashMap<u32, String> = HashMap::new();
1267 expected_symbol_table.insert(1, "IBIS".to_string());
1268 expected_symbol_table.insert(2, "COOT".to_string());
1269
1270 assert_eq!(
1271 DecodedRules::Composite(DecodedCompositeBindRules {
1272 symbol_table: expected_symbol_table,
1273 device_name_id: 1,
1274 primary_node: Node {
1275 name_id: 2,
1276 instructions: primary_node_inst.to_vec(),
1277 decoded_instructions: vec![
1278 DecodedInstruction::UnconditionalAbort,
1279 DecodedInstruction::Condition(DecodedCondition {
1280 is_equal: true,
1281 lhs: Symbol::NumberValue(0x5000000),
1282 rhs: Symbol::NumberValue(0x200010),
1283 }),
1284 ],
1285 },
1286 additional_nodes: vec![],
1287 optional_nodes: vec![],
1288 debug_info: None,
1289 }),
1290 DecodedRules::new(bytecode).unwrap()
1291 );
1292 }
1293
1294 #[test]
1295 fn test_missing_device_name() {
1296 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1297 bytecode.push(BYTECODE_DISABLE_DEBUG);
1298 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 9);
1299
1300 let primary_node_name: [u8; 5] = [0x43, 0x4F, 0x4F, 0x54, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1302 bytecode.extend_from_slice(&primary_node_name);
1303
1304 let primary_node_inst = [0x30];
1305 let composite_insts_sz =
1306 COMPOSITE_NAME_ID_BYTES + (NODE_TYPE_HEADER_SZ + primary_node_inst.len()) as u32;
1307 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1308 bytecode.extend_from_slice(&[2, 0, 0, 0]);
1309
1310 append_node_header(&mut bytecode, RawNodeType::Primary, 1, primary_node_inst.len() as u32);
1311 bytecode.extend_from_slice(&primary_node_inst);
1312
1313 assert_eq!(Err(BytecodeError::MissingDeviceNameInSymbolTable), DecodedRules::new(bytecode));
1314 }
1315
1316 #[test]
1317 fn test_missing_node_name() {
1318 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1319 bytecode.push(BYTECODE_DISABLE_DEBUG);
1320 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 9);
1321
1322 let primary_node_name: [u8; 5] = [0x43, 0x4F, 0x4F, 0x54, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1324 bytecode.extend_from_slice(&primary_node_name);
1325
1326 let primary_node_inst = [0x30];
1327 let composite_insts_sz =
1328 COMPOSITE_NAME_ID_BYTES + (NODE_TYPE_HEADER_SZ + primary_node_inst.len()) as u32;
1329 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1330 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1331
1332 append_node_header(&mut bytecode, RawNodeType::Primary, 2, primary_node_inst.len() as u32);
1333 bytecode.extend_from_slice(&primary_node_inst);
1334
1335 assert_eq!(Err(BytecodeError::MissingNodeIdInSymbolTable), DecodedRules::new(bytecode));
1336 }
1337
1338 #[test]
1339 fn test_missing_primary_node() {
1340 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1341 bytecode.push(BYTECODE_DISABLE_DEBUG);
1342 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 29);
1343
1344 let device_name: [u8; 5] = [0x4C, 0x4F, 0x4F, 0x4E, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1346 bytecode.extend_from_slice(&device_name);
1347
1348 let primary_node_name: [u8; 6] = [0x47, 0x52, 0x45, 0x42, 0x45, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1350 bytecode.extend_from_slice(&primary_node_name);
1351
1352 let additional_node_name: [u8; 6] = [0x53, 0x43, 0x41, 0x55, 0x50, 0]; bytecode.extend_from_slice(&[3, 0, 0, 0]);
1354 bytecode.extend_from_slice(&additional_node_name);
1355
1356 let additional_node_inst_1 = [0x02, 0x01, 0, 0, 0, 0x02, 0x02, 0, 0, 0x10];
1357 let additional_node_inst_2 = [0x30];
1358
1359 let composite_insts_sz = COMPOSITE_NAME_ID_BYTES
1360 + ((NODE_TYPE_HEADER_SZ * 2)
1361 + additional_node_inst_1.len()
1362 + additional_node_inst_2.len()) as u32;
1363 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1364
1365 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1367
1368 append_node_header(
1370 &mut bytecode,
1371 RawNodeType::Additional,
1372 2,
1373 additional_node_inst_1.len() as u32,
1374 );
1375 bytecode.extend_from_slice(&additional_node_inst_1);
1376 append_node_header(
1377 &mut bytecode,
1378 RawNodeType::Additional,
1379 3,
1380 additional_node_inst_2.len() as u32,
1381 );
1382 bytecode.extend_from_slice(&additional_node_inst_2);
1383
1384 assert_eq!(Err(BytecodeError::InvalidPrimaryNode), DecodedRules::new(bytecode));
1385 }
1386
1387 #[test]
1388 fn test_primary_node_incorrect_order() {
1389 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1390 bytecode.push(BYTECODE_DISABLE_DEBUG);
1391 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 29);
1392
1393 let device_name: [u8; 5] = [0x4C, 0x4F, 0x4F, 0x4E, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1395 bytecode.extend_from_slice(&device_name);
1396
1397 let primary_node_name: [u8; 6] = [0x47, 0x52, 0x45, 0x42, 0x45, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1399 bytecode.extend_from_slice(&primary_node_name);
1400
1401 let additional_node_name: [u8; 6] = [0x53, 0x43, 0x41, 0x55, 0x50, 0]; bytecode.extend_from_slice(&[3, 0, 0, 0]);
1403 bytecode.extend_from_slice(&additional_node_name);
1404
1405 let primary_node_inst = [0x02, 0x01, 0, 0, 0, 0x02, 0x02, 0, 0, 0x10];
1406 let additional_node_inst = [0x30];
1407
1408 let composite_insts_sz = COMPOSITE_NAME_ID_BYTES
1409 + ((NODE_TYPE_HEADER_SZ * 2) + primary_node_inst.len() + additional_node_inst.len())
1410 as u32;
1411 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1412
1413 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1415
1416 append_node_header(
1418 &mut bytecode,
1419 RawNodeType::Additional,
1420 3,
1421 additional_node_inst.len() as u32,
1422 );
1423 bytecode.extend_from_slice(&additional_node_inst);
1424 append_node_header(&mut bytecode, RawNodeType::Primary, 2, primary_node_inst.len() as u32);
1425 bytecode.extend_from_slice(&primary_node_inst);
1426
1427 assert_eq!(Err(BytecodeError::InvalidPrimaryNode), DecodedRules::new(bytecode));
1428 }
1429
1430 #[test]
1431 fn test_multiple_primary_nodes() {
1432 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1433 bytecode.push(BYTECODE_DISABLE_DEBUG);
1434 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 29);
1435
1436 let device_name: [u8; 5] = [0x4C, 0x4F, 0x4F, 0x4E, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1438 bytecode.extend_from_slice(&device_name);
1439
1440 let primary_node_name: [u8; 6] = [0x47, 0x52, 0x45, 0x42, 0x45, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1442 bytecode.extend_from_slice(&primary_node_name);
1443
1444 let primary_node_name_2: [u8; 6] = [0x53, 0x43, 0x41, 0x55, 0x50, 0]; bytecode.extend_from_slice(&[3, 0, 0, 0]);
1446 bytecode.extend_from_slice(&primary_node_name_2);
1447
1448 let primary_node_inst = [0x02, 0x01, 0, 0, 0, 0x02, 0x01, 0, 0, 0, 0x10];
1449 let primary_node_inst_2 = [0x30];
1450
1451 let composite_insts_sz = COMPOSITE_NAME_ID_BYTES
1452 + ((NODE_TYPE_HEADER_SZ * 2) + primary_node_inst.len() + primary_node_inst_2.len())
1453 as u32;
1454 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1455
1456 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1458
1459 append_node_header(&mut bytecode, RawNodeType::Primary, 2, primary_node_inst.len() as u32);
1461 bytecode.extend_from_slice(&primary_node_inst);
1462 append_node_header(
1463 &mut bytecode,
1464 RawNodeType::Primary,
1465 3,
1466 primary_node_inst_2.len() as u32,
1467 );
1468 bytecode.extend_from_slice(&primary_node_inst_2);
1469
1470 assert_eq!(Err(BytecodeError::MultiplePrimaryNodes), DecodedRules::new(bytecode));
1471 }
1472
1473 #[test]
1474 fn test_invalid_node_type() {
1475 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1476 bytecode.push(BYTECODE_DISABLE_DEBUG);
1477 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 18);
1478
1479 let device_name: [u8; 5] = [0x49, 0x42, 0x49, 0x53, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1481 bytecode.extend_from_slice(&device_name);
1482
1483 let primary_node_name: [u8; 5] = [0x52, 0x41, 0x49, 0x4C, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1485 bytecode.extend_from_slice(&primary_node_name);
1486
1487 let primary_node_inst = [0x30];
1488
1489 let composite_insts_sz =
1490 COMPOSITE_NAME_ID_BYTES + (NODE_TYPE_HEADER_SZ + primary_node_inst.len()) as u32;
1491 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1492
1493 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1495
1496 bytecode.push(0x53);
1498 bytecode.extend_from_slice(&[2, 0, 0, 0]);
1499 bytecode.extend_from_slice(&(primary_node_inst.len() as u32).to_le_bytes());
1500 bytecode.extend_from_slice(&primary_node_inst);
1501
1502 assert_eq!(Err(BytecodeError::InvalidNodeType(0x53)), DecodedRules::new(bytecode));
1503 }
1504
1505 #[test]
1506 fn test_incorrect_node_section_sz_overlap() {
1507 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1508 bytecode.push(BYTECODE_DISABLE_DEBUG);
1509 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 27);
1510
1511 let device_name: [u8; 5] = [0x49, 0x42, 0x49, 0x53, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1513 bytecode.extend_from_slice(&device_name);
1514
1515 let primary_node_name: [u8; 5] = [0x52, 0x41, 0x49, 0x4C, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1517 bytecode.extend_from_slice(&primary_node_name);
1518
1519 let node_name_1: [u8; 5] = [0x43, 0x4F, 0x4F, 0x54, 0]; bytecode.extend_from_slice(&[3, 0, 0, 0]);
1521 bytecode.extend_from_slice(&node_name_1);
1522
1523 let primary_node_inst = [0x30];
1524 let additional_node_inst = [0x02, 0x01, 0, 0, 0, 0x02, 0x02, 0, 0, 0x10];
1525
1526 let composite_insts_sz = COMPOSITE_NAME_ID_BYTES
1527 + ((NODE_TYPE_HEADER_SZ * 2) + primary_node_inst.len() + additional_node_inst.len())
1528 as u32;
1529 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1530
1531 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1533
1534 append_node_header(&mut bytecode, RawNodeType::Primary, 2, 7);
1537 bytecode.extend_from_slice(&primary_node_inst);
1538
1539 append_node_header(
1540 &mut bytecode,
1541 RawNodeType::Additional,
1542 3,
1543 additional_node_inst.len() as u32,
1544 );
1545 bytecode.extend_from_slice(&additional_node_inst);
1546
1547 assert_eq!(
1549 Err(BytecodeError::InvalidOp(RawNodeType::Additional as u8)),
1550 DecodedRules::new(bytecode)
1551 );
1552 }
1553
1554 #[test]
1555 fn test_incorrect_node_section_sz_undersize() {
1556 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1557 bytecode.push(BYTECODE_DISABLE_DEBUG);
1558 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 27);
1559
1560 let device_name: [u8; 5] = [0x49, 0x42, 0x49, 0x53, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1562 bytecode.extend_from_slice(&device_name);
1563
1564 let primary_node_name: [u8; 5] = [0x52, 0x41, 0x49, 0x4C, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1566 bytecode.extend_from_slice(&primary_node_name);
1567
1568 let node_name_1: [u8; 5] = [0x43, 0x4F, 0x4F, 0x54, 0]; bytecode.extend_from_slice(&[3, 0, 0, 0]);
1570 bytecode.extend_from_slice(&node_name_1);
1571
1572 let primary_node_inst = [0x30];
1573 let additional_node_inst = [0x02, 0x01, 0, 0, 0, 0x02, 0x02, 0, 0, 0x10];
1574
1575 let composite_insts_sz = COMPOSITE_NAME_ID_BYTES
1576 + ((NODE_TYPE_HEADER_SZ * 2) + primary_node_inst.len() + additional_node_inst.len())
1577 as u32;
1578 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1579
1580 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1582
1583 append_node_header(&mut bytecode, RawNodeType::Primary, 2, primary_node_inst.len() as u32);
1584 bytecode.extend_from_slice(&primary_node_inst);
1585
1586 append_node_header(&mut bytecode, RawNodeType::Additional, 3, 1);
1588 bytecode.extend_from_slice(&additional_node_inst);
1589
1590 assert_eq!(Err(BytecodeError::UnexpectedEnd), DecodedRules::new(bytecode));
1592 }
1593
1594 #[test]
1595 fn test_incorrect_node_section_sz_oversize() {
1596 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1597 bytecode.push(BYTECODE_DISABLE_DEBUG);
1598 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 18);
1599
1600 let device_name: [u8; 5] = [0x49, 0x42, 0x49, 0x53, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1602 bytecode.extend_from_slice(&device_name);
1603
1604 let primary_node_name: [u8; 5] = [0x43, 0x4F, 0x4F, 0x54, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1606 bytecode.extend_from_slice(&primary_node_name);
1607
1608 let primary_node_inst = [0x30, 0x01, 0x01, 0, 0, 0, 0x05, 0x01, 0x10, 0, 0x20, 0];
1609
1610 let composite_insts_sz =
1611 COMPOSITE_NAME_ID_BYTES + (NODE_TYPE_HEADER_SZ + primary_node_inst.len()) as u32;
1612 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1613
1614 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1616
1617 append_node_header(&mut bytecode, RawNodeType::Primary, 2, 50);
1619 bytecode.extend_from_slice(&primary_node_inst);
1620
1621 assert_eq!(Err(BytecodeError::IncorrectNodeSectionSize), DecodedRules::new(bytecode));
1622 }
1623
1624 #[test]
1625 fn test_composite_header_in_noncomposite_bytecode() {
1626 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1627 bytecode.push(BYTECODE_DISABLE_DEBUG);
1628 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 18);
1629
1630 let str_1: [u8; 5] = [0x49, 0x42, 0x49, 0x53, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1632 bytecode.extend_from_slice(&str_1);
1633
1634 let primary_node_name: [u8; 5] = [0x52, 0x41, 0x49, 0x4C, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1636 bytecode.extend_from_slice(&primary_node_name);
1637
1638 let primary_node_inst = [0x30, 0x01, 0x01, 0, 0, 0, 0x05, 0x01, 0x10, 0, 0x20, 0];
1639
1640 let composite_insts_sz =
1641 COMPOSITE_NAME_ID_BYTES + (NODE_TYPE_HEADER_SZ + primary_node_inst.len()) as u32;
1642 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1643
1644 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1646
1647 append_node_header(&mut bytecode, RawNodeType::Primary, 2, primary_node_inst.len() as u32);
1649 bytecode.extend_from_slice(&primary_node_inst);
1650
1651 assert_eq!(
1652 Err(BytecodeError::InvalidHeader(INSTRUCTION_MAGIC_NUM, COMPOSITE_MAGIC_NUM)),
1653 DecodedBindRules::from_bytecode(bytecode)
1654 );
1655 }
1656
1657 #[test]
1658 fn test_inst_header_in_composite_bytecode() {
1659 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1660 bytecode.push(BYTECODE_DISABLE_DEBUG);
1661 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
1662
1663 let instructions = [0x30, 0x01, 0x01, 0, 0, 0, 0x05, 0x10, 0, 0, 0x10];
1664 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, instructions.len() as u32);
1665 bytecode.extend_from_slice(&instructions);
1666
1667 assert_eq!(
1668 Err(BytecodeError::InvalidHeader(COMPOSITE_MAGIC_NUM, INSTRUCTION_MAGIC_NUM)),
1669 DecodedCompositeBindRules::from_bytecode(bytecode)
1670 );
1671 }
1672
1673 #[test]
1674 fn test_composite_with_compiler() {
1675 use crate::compiler::{
1676 CompiledBindRules, CompositeBindRules, CompositeNode, Symbol, SymbolicInstruction,
1677 SymbolicInstructionInfo,
1678 };
1679 use crate::parser::bind_library::ValueType;
1680
1681 let primary_node_inst = vec![SymbolicInstructionInfo {
1682 location: None,
1683 instruction: SymbolicInstruction::UnconditionalAbort,
1684 }];
1685
1686 let additional_node_inst = vec![
1687 SymbolicInstructionInfo {
1688 location: None,
1689 instruction: SymbolicInstruction::AbortIfEqual {
1690 lhs: Symbol::Key("bobolink".to_string(), ValueType::Bool),
1691 rhs: Symbol::BoolValue(false),
1692 },
1693 },
1694 SymbolicInstructionInfo {
1695 location: None,
1696 instruction: SymbolicInstruction::AbortIfNotEqual {
1697 lhs: Symbol::Key("grackle".to_string(), ValueType::Number),
1698 rhs: Symbol::NumberValue(1),
1699 },
1700 },
1701 ];
1702
1703 let bytecode = CompiledBindRules::CompositeBind(CompositeBindRules {
1704 device_name: "blackbird".to_string(),
1705 symbol_table: HashMap::new(),
1706 primary_node: CompositeNode {
1707 name: "meadowlark".to_string(),
1708 instructions: primary_node_inst,
1709 },
1710 additional_nodes: vec![CompositeNode {
1711 name: "cowbird".to_string(),
1712 instructions: additional_node_inst,
1713 }],
1714 optional_nodes: vec![],
1715 enable_debug: false,
1716 })
1717 .encode_to_bytecode()
1718 .unwrap();
1719
1720 let mut expected_symbol_table: HashMap<u32, String> = HashMap::new();
1721 expected_symbol_table.insert(1, "blackbird".to_string());
1722 expected_symbol_table.insert(2, "meadowlark".to_string());
1723 expected_symbol_table.insert(3, "cowbird".to_string());
1724 expected_symbol_table.insert(4, "bobolink".to_string());
1725 expected_symbol_table.insert(5, "grackle".to_string());
1726
1727 let primary_node_inst = [0x30];
1728 let additional_node_inst = [
1729 0x02, 0x0, 0x04, 0x0, 0x0, 0x0, 0x03, 0x0, 0x0, 0x0, 0x0, 0x01, 0x0, 0x05, 0x0, 0x0, 0x0, 0x01, 0x1, 0x0, 0x0, 0x0, ];
1732
1733 assert_eq!(
1734 DecodedRules::Composite(DecodedCompositeBindRules {
1735 symbol_table: expected_symbol_table,
1736 device_name_id: 1,
1737 primary_node: Node {
1738 name_id: 2,
1739 instructions: primary_node_inst.to_vec(),
1740 decoded_instructions: vec![DecodedInstruction::UnconditionalAbort],
1741 },
1742 additional_nodes: vec![Node {
1743 name_id: 3,
1744 instructions: additional_node_inst.to_vec(),
1745 decoded_instructions: vec![
1746 DecodedInstruction::Condition(DecodedCondition {
1747 is_equal: false,
1748 lhs: Symbol::Key("bobolink".to_string(), ValueType::Str),
1749 rhs: Symbol::BoolValue(false)
1750 }),
1751 DecodedInstruction::Condition(DecodedCondition {
1752 is_equal: true,
1753 lhs: Symbol::Key("grackle".to_string(), ValueType::Str),
1754 rhs: Symbol::NumberValue(1)
1755 })
1756 ]
1757 }],
1758 optional_nodes: vec![],
1759 debug_info: None,
1760 }),
1761 DecodedRules::new(bytecode).unwrap()
1762 );
1763 }
1764
1765 #[test]
1766 fn test_composite_optional_with_compiler() {
1767 use crate::compiler::{
1768 CompiledBindRules, CompositeBindRules, CompositeNode, Symbol, SymbolicInstruction,
1769 SymbolicInstructionInfo,
1770 };
1771 use crate::parser::bind_library::ValueType;
1772
1773 let primary_node_inst = vec![SymbolicInstructionInfo {
1774 location: None,
1775 instruction: SymbolicInstruction::UnconditionalAbort,
1776 }];
1777
1778 let additional_node_inst = vec![
1779 SymbolicInstructionInfo {
1780 location: None,
1781 instruction: SymbolicInstruction::AbortIfEqual {
1782 lhs: Symbol::Key("bobolink".to_string(), ValueType::Bool),
1783 rhs: Symbol::BoolValue(false),
1784 },
1785 },
1786 SymbolicInstructionInfo {
1787 location: None,
1788 instruction: SymbolicInstruction::AbortIfNotEqual {
1789 lhs: Symbol::Key("grackle".to_string(), ValueType::Number),
1790 rhs: Symbol::NumberValue(1),
1791 },
1792 },
1793 ];
1794
1795 let optional_node_inst = vec![SymbolicInstructionInfo {
1796 location: None,
1797 instruction: SymbolicInstruction::AbortIfEqual {
1798 lhs: Symbol::Key("mockingbird".to_string(), ValueType::Bool),
1799 rhs: Symbol::BoolValue(false),
1800 },
1801 }];
1802
1803 let bytecode = CompiledBindRules::CompositeBind(CompositeBindRules {
1804 device_name: "blackbird".to_string(),
1805 symbol_table: HashMap::new(),
1806 primary_node: CompositeNode {
1807 name: "meadowlark".to_string(),
1808 instructions: primary_node_inst,
1809 },
1810 additional_nodes: vec![CompositeNode {
1811 name: "cowbird".to_string(),
1812 instructions: additional_node_inst,
1813 }],
1814 optional_nodes: vec![CompositeNode {
1815 name: "cowbird_optional".to_string(),
1816 instructions: optional_node_inst,
1817 }],
1818 enable_debug: false,
1819 })
1820 .encode_to_bytecode()
1821 .unwrap();
1822
1823 let mut expected_symbol_table: HashMap<u32, String> = HashMap::new();
1824 expected_symbol_table.insert(1, "blackbird".to_string());
1825 expected_symbol_table.insert(2, "meadowlark".to_string());
1826 expected_symbol_table.insert(3, "cowbird".to_string());
1827 expected_symbol_table.insert(4, "bobolink".to_string());
1828 expected_symbol_table.insert(5, "grackle".to_string());
1829 expected_symbol_table.insert(6, "cowbird_optional".to_string());
1830 expected_symbol_table.insert(7, "mockingbird".to_string());
1831
1832 let primary_node_inst = [0x30];
1833 let additional_node_inst = [
1834 0x02, 0x0, 0x04, 0x0, 0x0, 0x0, 0x03, 0x0, 0x0, 0x0, 0x0, 0x01, 0x0, 0x05, 0x0, 0x0, 0x0, 0x01, 0x1, 0x0, 0x0, 0x0, ];
1837
1838 let optional_node_inst = [
1839 0x02, 0x0, 0x07, 0x0, 0x0, 0x0, 0x03, 0x0, 0x0, 0x0, 0x0, ];
1841
1842 assert_eq!(
1843 DecodedRules::Composite(DecodedCompositeBindRules {
1844 symbol_table: expected_symbol_table,
1845 device_name_id: 1,
1846 primary_node: Node {
1847 name_id: 2,
1848 instructions: primary_node_inst.to_vec(),
1849 decoded_instructions: vec![DecodedInstruction::UnconditionalAbort],
1850 },
1851 additional_nodes: vec![Node {
1852 name_id: 3,
1853 instructions: additional_node_inst.to_vec(),
1854 decoded_instructions: vec![
1855 DecodedInstruction::Condition(DecodedCondition {
1856 is_equal: false,
1857 lhs: Symbol::Key("bobolink".to_string(), ValueType::Str),
1858 rhs: Symbol::BoolValue(false)
1859 }),
1860 DecodedInstruction::Condition(DecodedCondition {
1861 is_equal: true,
1862 lhs: Symbol::Key("grackle".to_string(), ValueType::Str),
1863 rhs: Symbol::NumberValue(1)
1864 })
1865 ]
1866 }],
1867 optional_nodes: vec![Node {
1868 name_id: 6,
1869 instructions: optional_node_inst.to_vec(),
1870 decoded_instructions: vec![DecodedInstruction::Condition(DecodedCondition {
1871 is_equal: false,
1872 lhs: Symbol::Key("mockingbird".to_string(), ValueType::Str),
1873 rhs: Symbol::BoolValue(false)
1874 })],
1875 }],
1876 debug_info: None,
1877 }),
1878 DecodedRules::new(bytecode).unwrap()
1879 );
1880 }
1881}