1#[cfg(has_asm)]
2pub mod asm;
3pub mod trace;
4
5use std::fmt::{self, Display};
6use std::sync::atomic::{AtomicU8, Ordering};
7use std::sync::Arc;
8
9use bytes::Bytes;
10
11use super::debugger::Debugger;
12use super::decoder::{build_decoder, Decoder};
13use super::elf::{parse_elf, LoadingAction, ProgramMetadata};
14use super::instructions::{execute, Instruction, Register};
15use super::memory::{load_c_string_byte_by_byte, Memory};
16use super::syscalls::Syscalls;
17use super::{
18 registers::{A0, A7, REGISTER_ABI_NAMES, SP},
19 Error, ISA_MOP, RISCV_GENERAL_REGISTER_NUMBER, RISCV_MAX_MEMORY,
20};
21
22pub const VERSION0: u32 = 0;
24pub const VERSION1: u32 = 1;
31pub const VERSION2: u32 = 2;
32
33pub trait CoreMachine {
37 type REG: Register;
38 type MEM: Memory<REG = Self::REG>;
39
40 fn pc(&self) -> &Self::REG;
41 fn update_pc(&mut self, pc: Self::REG);
42 fn commit_pc(&mut self);
43 fn memory(&self) -> &Self::MEM;
44 fn memory_mut(&mut self) -> &mut Self::MEM;
45 fn registers(&self) -> &[Self::REG];
46 fn set_register(&mut self, idx: usize, value: Self::REG);
47
48 fn version(&self) -> u32;
51 fn isa(&self) -> u8;
52}
53
54pub trait Machine: CoreMachine {
57 fn ecall(&mut self) -> Result<(), Error>;
58 fn ebreak(&mut self) -> Result<(), Error>;
59}
60
61pub trait SupportMachine: CoreMachine {
65 fn new(isa: u8, version: u32, max_cycles: u64) -> Self
67 where
68 Self: Sized,
69 {
70 Self::new_with_memory(isa, version, max_cycles, RISCV_MAX_MEMORY)
71 }
72
73 fn new_with_memory(isa: u8, version: u32, max_cycles: u64, memory_size: usize) -> Self
75 where
76 Self: Sized;
77
78 fn cycles(&self) -> u64;
83 fn set_cycles(&mut self, cycles: u64);
84 fn max_cycles(&self) -> u64;
85 fn set_max_cycles(&mut self, cycles: u64);
86
87 fn running(&self) -> bool;
88 fn set_running(&mut self, running: bool);
89
90 fn reset(&mut self, max_cycles: u64);
92 fn reset_signal(&mut self) -> bool;
93
94 fn add_cycles(&mut self, cycles: u64) -> Result<(), Error> {
95 let new_cycles = self
96 .cycles()
97 .checked_add(cycles)
98 .ok_or(Error::CyclesOverflow)?;
99 if new_cycles > self.max_cycles() {
100 return Err(Error::CyclesExceeded);
101 }
102 self.set_cycles(new_cycles);
103 Ok(())
104 }
105
106 fn add_cycles_no_checking(&mut self, cycles: u64) -> Result<(), Error> {
107 let new_cycles = self
108 .cycles()
109 .checked_add(cycles)
110 .ok_or(Error::CyclesOverflow)?;
111 self.set_cycles(new_cycles);
112 Ok(())
113 }
114
115 fn load_elf_inner(&mut self, program: &Bytes, update_pc: bool) -> Result<u64, Error> {
116 let version = self.version();
117 let metadata = parse_elf::<Self::REG>(program, version)?;
118 self.load_binary(program, &metadata, update_pc)
119 }
120
121 fn load_elf(&mut self, program: &Bytes, update_pc: bool) -> Result<u64, Error> {
122 self.load_elf_inner(program, update_pc)
133 }
134
135 fn load_binary_inner(
136 &mut self,
137 program: &Bytes,
138 metadata: &ProgramMetadata,
139 update_pc: bool,
140 ) -> Result<u64, Error> {
141 let version = self.version();
142 let mut bytes: u64 = 0;
143 for action in &metadata.actions {
144 let LoadingAction {
145 addr,
146 size,
147 flags,
148 source,
149 offset_from_addr,
150 } = action;
151
152 self.memory_mut().init_pages(
153 *addr,
154 *size,
155 *flags,
156 Some(program.slice(source.start as usize..source.end as usize)),
157 *offset_from_addr,
158 )?;
159 if version < VERSION1 {
160 self.memory_mut().store_byte(*addr, *offset_from_addr, 0)?;
161 }
162 bytes = bytes
163 .checked_add(source.end - source.start)
164 .ok_or_else(|| {
165 Error::Unexpected(String::from("The bytes count overflowed on loading elf"))
166 })?;
167 }
168 if update_pc {
169 self.update_pc(Self::REG::from_u64(metadata.entry));
170 self.commit_pc();
171 }
172 Ok(bytes)
173 }
174
175 fn load_binary(
176 &mut self,
177 program: &Bytes,
178 metadata: &ProgramMetadata,
179 update_pc: bool,
180 ) -> Result<u64, Error> {
181 self.load_binary_inner(program, metadata, update_pc)
183 }
184
185 fn initialize_stack(
186 &mut self,
187 args: impl ExactSizeIterator<Item = Result<Bytes, Error>>,
188 stack_start: u64,
189 stack_size: u64,
190 ) -> Result<u64, Error> {
191 if self.version() >= VERSION1 && args.len() == 0 {
200 let argc_size = u64::from(Self::REG::BITS / 8);
201 let origin_sp = stack_start + stack_size;
202 let unaligned_sp_address = origin_sp - argc_size;
203 let aligned_sp_address = unaligned_sp_address & (!15);
204 let used_bytes = origin_sp - aligned_sp_address;
205 self.set_register(SP, Self::REG::from_u64(aligned_sp_address));
206 return Ok(used_bytes);
207 }
208
209 self.set_register(SP, Self::REG::from_u64(stack_start + stack_size));
212 let mut values = vec![Self::REG::from_u64(args.len() as u64)];
215 for arg in args {
216 let arg = arg?;
217 let len = Self::REG::from_u64(arg.len() as u64 + 1);
218 let address = self.registers()[SP].overflowing_sub(&len);
219
220 self.memory_mut().store_bytes(address.to_u64(), &arg)?;
221 self.memory_mut()
222 .store_byte(address.to_u64() + arg.len() as u64, 1, 0)?;
223
224 values.push(address.clone());
225 self.set_register(SP, address.clone());
226
227 if self.version() >= VERSION2 && address.to_u64() < stack_start {
228 return Err(Error::MemOutOfStack);
230 }
231 }
232 if self.version() >= VERSION1 {
233 values.push(Self::REG::zero());
237 let values_bytes =
241 Self::REG::from_u64(Self::REG::BITS as u64 / 8 * values.len() as u64);
242 let unaligned_sp_address = self.registers()[SP].overflowing_sub(&values_bytes).to_u64();
243 let aligned_sp_address = unaligned_sp_address & (!15);
245 let aligned_bytes = unaligned_sp_address - aligned_sp_address;
246 self.set_register(
247 SP,
248 self.registers()[SP].overflowing_sub(&Self::REG::from_u64(aligned_bytes)),
249 );
250 }
251 for value in values.iter().rev() {
254 let address =
255 self.registers()[SP].overflowing_sub(&Self::REG::from_u8(Self::REG::BITS / 8));
256 if self.version() >= VERSION1 {
257 if Self::REG::BITS == 64 {
258 self.memory_mut().store64(&address, value)?;
259 } else {
260 self.memory_mut().store32(&address, value)?;
261 }
262 } else {
263 self.memory_mut().store32(&address, value)?;
264 }
265 self.set_register(SP, address);
266 }
267 if self.registers()[SP].to_u64() < stack_start {
268 return Err(Error::MemOutOfStack);
270 }
271 Ok(stack_start + stack_size - self.registers()[SP].to_u64())
272 }
273
274 #[cfg(feature = "pprof")]
275 fn code(&self) -> &Bytes;
276}
277
278pub trait DefaultMachineRunner {
280 type Inner: SupportMachine;
281
282 fn new(machine: DefaultMachine<Self::Inner>) -> Self;
284
285 fn machine(&self) -> &DefaultMachine<Self::Inner>;
287
288 fn machine_mut(&mut self) -> &mut DefaultMachine<Self::Inner>;
290
291 fn run(&mut self) -> Result<i8, Error>;
293
294 fn inner_mut(&mut self) -> &mut Self::Inner {
296 self.machine_mut().inner_mut()
297 }
298
299 fn load_program(
301 &mut self,
302 program: &Bytes,
303 args: impl ExactSizeIterator<Item = Result<Bytes, Error>>,
304 ) -> Result<u64, Error> {
305 self.machine_mut().load_program(program, args)
306 }
307
308 fn load_program_with_metadata(
310 &mut self,
311 program: &Bytes,
312 metadata: &ProgramMetadata,
313 args: impl ExactSizeIterator<Item = Result<Bytes, Error>>,
314 ) -> Result<u64, Error> {
315 self.machine_mut()
316 .load_program_with_metadata(program, metadata, args)
317 }
318}
319
320#[derive(Default)]
321pub struct DefaultCoreMachine<R, M> {
322 registers: [R; RISCV_GENERAL_REGISTER_NUMBER],
323 pc: R,
324 next_pc: R,
325 reset_signal: bool,
326 memory: M,
327 cycles: u64,
328 max_cycles: u64,
329 running: bool,
330 isa: u8,
331 version: u32,
332 #[cfg(feature = "pprof")]
333 code: Bytes,
334}
335
336impl<R: Register, M: Memory<REG = R>> CoreMachine for DefaultCoreMachine<R, M> {
337 type REG = R;
338 type MEM = M;
339 fn pc(&self) -> &Self::REG {
340 &self.pc
341 }
342
343 fn update_pc(&mut self, pc: Self::REG) {
344 self.next_pc = pc;
345 }
346
347 fn commit_pc(&mut self) {
348 self.pc = self.next_pc.clone();
349 }
350
351 fn memory(&self) -> &Self::MEM {
352 &self.memory
353 }
354
355 fn memory_mut(&mut self) -> &mut Self::MEM {
356 &mut self.memory
357 }
358
359 fn registers(&self) -> &[Self::REG] {
360 &self.registers
361 }
362
363 fn set_register(&mut self, idx: usize, value: Self::REG) {
364 self.registers[idx] = value;
365 }
366
367 fn isa(&self) -> u8 {
368 self.isa
369 }
370
371 fn version(&self) -> u32 {
372 self.version
373 }
374}
375
376impl<R: Register, M: Memory<REG = R>> SupportMachine for DefaultCoreMachine<R, M> {
377 fn new_with_memory(isa: u8, version: u32, max_cycles: u64, memory_size: usize) -> Self {
378 Self {
379 registers: Default::default(),
380 pc: Default::default(),
381 next_pc: Default::default(),
382 reset_signal: Default::default(),
383 memory: M::new_with_memory(memory_size),
384 cycles: Default::default(),
385 max_cycles,
386 running: Default::default(),
387 isa,
388 version,
389 #[cfg(feature = "pprof")]
390 code: Default::default(),
391 }
392 }
393
394 fn cycles(&self) -> u64 {
395 self.cycles
396 }
397
398 fn set_cycles(&mut self, cycles: u64) {
399 self.cycles = cycles;
400 }
401
402 fn max_cycles(&self) -> u64 {
403 self.max_cycles
404 }
405
406 fn set_max_cycles(&mut self, max_cycles: u64) {
407 self.max_cycles = max_cycles;
408 }
409
410 fn reset(&mut self, max_cycles: u64) {
411 self.registers = Default::default();
412 self.pc = Default::default();
413 self.memory = M::new_with_memory(self.memory().memory_size());
414 self.cycles = 0;
415 self.max_cycles = max_cycles;
416 self.reset_signal = true;
417 self.memory_mut().set_lr(&R::from_u64(u64::MAX));
418 }
419
420 fn reset_signal(&mut self) -> bool {
421 let ret = self.reset_signal;
422 self.reset_signal = false;
423 ret
424 }
425
426 fn running(&self) -> bool {
427 self.running
428 }
429
430 fn set_running(&mut self, running: bool) {
431 self.running = running;
432 }
433
434 fn load_binary(
435 &mut self,
436 program: &Bytes,
437 metadata: &ProgramMetadata,
438 update_pc: bool,
439 ) -> Result<u64, Error> {
440 #[cfg(feature = "pprof")]
441 {
442 self.code = program.clone();
443 }
444 self.load_binary_inner(program, metadata, update_pc)
445 }
446
447 fn load_elf(&mut self, program: &Bytes, update_pc: bool) -> Result<u64, Error> {
448 #[cfg(feature = "pprof")]
449 {
450 self.code = program.clone();
451 }
452 self.load_elf_inner(program, update_pc)
453 }
454
455 #[cfg(feature = "pprof")]
456 fn code(&self) -> &Bytes {
457 &self.code
458 }
459}
460
461impl<R: Register, M: Memory> DefaultCoreMachine<R, M> {
462 pub fn set_max_cycles(&mut self, cycles: u64) {
463 self.max_cycles = cycles;
464 }
465
466 pub fn take_memory(self) -> M {
467 self.memory
468 }
469}
470
471pub type InstructionCycleFunc = dyn Fn(Instruction) -> u64 + Send + Sync;
472
473pub struct DefaultMachine<Inner> {
474 inner: Inner,
475 pause: Pause,
476
477 instruction_cycle_func: Box<InstructionCycleFunc>,
482 debugger: Option<Box<dyn Debugger<Inner>>>,
483 syscalls: Vec<Box<dyn Syscalls<Inner>>>,
484 exit_code: i8,
485}
486
487impl<Inner: CoreMachine> CoreMachine for DefaultMachine<Inner> {
488 type REG = <Inner as CoreMachine>::REG;
489 type MEM = <Inner as CoreMachine>::MEM;
490
491 fn pc(&self) -> &Self::REG {
492 self.inner.pc()
493 }
494
495 fn update_pc(&mut self, pc: Self::REG) {
496 self.inner.update_pc(pc);
497 }
498
499 fn commit_pc(&mut self) {
500 self.inner.commit_pc();
501 }
502
503 fn memory(&self) -> &Self::MEM {
504 self.inner.memory()
505 }
506
507 fn memory_mut(&mut self) -> &mut Self::MEM {
508 self.inner.memory_mut()
509 }
510
511 fn registers(&self) -> &[Self::REG] {
512 self.inner.registers()
513 }
514
515 fn set_register(&mut self, idx: usize, value: Self::REG) {
516 self.inner.set_register(idx, value)
517 }
518
519 fn isa(&self) -> u8 {
520 self.inner.isa()
521 }
522
523 fn version(&self) -> u32 {
524 self.inner.version()
525 }
526}
527
528impl<Inner: SupportMachine> SupportMachine for DefaultMachine<Inner> {
529 fn new_with_memory(_isa: u8, _version: u32, _max_cycles: u64, _memory_size: usize) -> Self {
530 panic!("Please instantiate DefaultMachine using DefaultMachineBuilder!");
531 }
532
533 fn cycles(&self) -> u64 {
534 self.inner.cycles()
535 }
536
537 fn set_cycles(&mut self, cycles: u64) {
538 self.inner.set_cycles(cycles)
539 }
540
541 fn max_cycles(&self) -> u64 {
542 self.inner.max_cycles()
543 }
544
545 fn set_max_cycles(&mut self, max_cycles: u64) {
546 self.inner.set_max_cycles(max_cycles)
547 }
548
549 fn reset(&mut self, max_cycles: u64) {
550 self.inner_mut().reset(max_cycles);
551 }
552
553 fn reset_signal(&mut self) -> bool {
554 self.inner_mut().reset_signal()
555 }
556
557 fn running(&self) -> bool {
558 self.inner.running()
559 }
560
561 fn set_running(&mut self, running: bool) {
562 self.inner.set_running(running);
563 }
564
565 fn load_binary(
566 &mut self,
567 program: &Bytes,
568 metadata: &ProgramMetadata,
569 update_pc: bool,
570 ) -> Result<u64, Error> {
571 self.inner.load_binary(program, metadata, update_pc)
572 }
573
574 fn load_elf(&mut self, program: &Bytes, update_pc: bool) -> Result<u64, Error> {
575 self.inner.load_elf(program, update_pc)
576 }
577
578 #[cfg(feature = "pprof")]
579 fn code(&self) -> &Bytes {
580 self.inner.code()
581 }
582}
583
584impl<Inner: SupportMachine> Machine for DefaultMachine<Inner> {
585 fn ecall(&mut self) -> Result<(), Error> {
586 let code = self.registers()[A7].to_u64();
587 match code {
588 93 => {
589 self.exit_code = self.registers()[A0].to_i8();
591 self.set_running(false);
592 Ok(())
593 }
594 _ => {
595 for syscall in &mut self.syscalls {
596 let processed = syscall.ecall(&mut self.inner)?;
597 if processed {
598 if self.cycles() > self.max_cycles() {
599 return Err(Error::CyclesExceeded);
600 }
601 return Ok(());
602 }
603 }
604 Err(Error::InvalidEcall(code))
605 }
606 }
607 }
608
609 fn ebreak(&mut self) -> Result<(), Error> {
610 if let Some(debugger) = &mut self.debugger {
611 debugger.ebreak(&mut self.inner)
612 } else {
613 Ok(())
616 }
617 }
618}
619
620impl<Inner: CoreMachine> Display for DefaultMachine<Inner> {
621 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
622 writeln!(f, "pc : 0x{:16X}", self.pc().to_u64())?;
623 for (i, name) in REGISTER_ABI_NAMES.iter().enumerate() {
624 write!(f, "{:4}: 0x{:16X}", name, self.registers()[i].to_u64())?;
625 if (i + 1) % 4 == 0 {
626 writeln!(f)?;
627 } else {
628 write!(f, " ")?;
629 }
630 }
631 Ok(())
632 }
633}
634
635impl<Inner: SupportMachine> DefaultMachineRunner for DefaultMachine<Inner> {
636 type Inner = Inner;
637
638 fn new(machine: DefaultMachine<Inner>) -> Self {
639 machine
640 }
641
642 fn machine(&self) -> &DefaultMachine<Inner> {
643 self
644 }
645
646 fn machine_mut(&mut self) -> &mut DefaultMachine<Inner> {
647 self
648 }
649
650 fn run(&mut self) -> Result<i8, Error> {
651 self.run()
652 }
653}
654
655impl<Inner: SupportMachine> DefaultMachine<Inner> {
656 pub fn load_program(
657 &mut self,
658 program: &Bytes,
659 args: impl ExactSizeIterator<Item = Result<Bytes, Error>>,
660 ) -> Result<u64, Error> {
661 let elf_bytes = self.load_elf(program, true)?;
662 let stack_bytes = self.initialize(args)?;
663 let bytes = elf_bytes.checked_add(stack_bytes).ok_or_else(|| {
664 Error::Unexpected(String::from(
665 "The bytes count overflowed on loading program",
666 ))
667 })?;
668 Ok(bytes)
669 }
670
671 pub fn load_program_with_metadata(
672 &mut self,
673 program: &Bytes,
674 metadata: &ProgramMetadata,
675 args: impl ExactSizeIterator<Item = Result<Bytes, Error>>,
676 ) -> Result<u64, Error> {
677 let elf_bytes = self.load_binary(program, metadata, true)?;
678 let stack_bytes = self.initialize(args)?;
679 let bytes = elf_bytes.checked_add(stack_bytes).ok_or_else(|| {
680 Error::Unexpected(String::from(
681 "The bytes count overflowed on loading program",
682 ))
683 })?;
684 Ok(bytes)
685 }
686
687 fn initialize(
688 &mut self,
689 args: impl ExactSizeIterator<Item = Result<Bytes, Error>>,
690 ) -> Result<u64, Error> {
691 for syscall in &mut self.syscalls {
692 syscall.initialize(&mut self.inner)?;
693 }
694 if let Some(debugger) = &mut self.debugger {
695 debugger.initialize(&mut self.inner)?;
696 }
697 let memory_size = self.memory().memory_size();
698 let stack_size = memory_size / 4;
699 let stack_bytes =
700 self.initialize_stack(args, (memory_size - stack_size) as u64, stack_size as u64)?;
701 if self.inner.version() >= VERSION1 {
703 debug_assert!(self.registers()[SP].to_u64() % 16 == 0);
704 }
705 Ok(stack_bytes)
706 }
707
708 pub fn take_inner(self) -> Inner {
709 self.inner
710 }
711
712 pub fn pause(&self) -> Pause {
713 self.pause.clone()
714 }
715
716 pub fn set_pause(&mut self, pause: Pause) {
717 self.pause = pause;
718 }
719
720 pub fn exit_code(&self) -> i8 {
721 self.exit_code
722 }
723
724 pub fn instruction_cycle_func(&self) -> &InstructionCycleFunc {
725 &self.instruction_cycle_func
726 }
727
728 pub fn inner_mut(&mut self) -> &mut Inner {
729 &mut self.inner
730 }
731
732 pub fn run(&mut self) -> Result<i8, Error> {
737 if self.isa() & ISA_MOP != 0 && self.version() == VERSION0 {
738 return Err(Error::InvalidVersion);
739 }
740 let mut decoder = build_decoder::<Inner::REG>(self.isa(), self.version());
741 self.set_running(true);
742 while self.running() {
743 if self.pause.has_interrupted() {
744 self.pause.free();
745 return Err(Error::Pause);
746 }
747 if self.reset_signal() {
748 decoder.reset_instructions_cache();
749 }
750 self.step(&mut decoder)?;
751 }
752 Ok(self.exit_code())
753 }
754
755 pub fn step(&mut self, decoder: &mut Decoder) -> Result<(), Error> {
756 let instruction = {
757 let pc = self.pc().to_u64();
758 let memory = self.memory_mut();
759 decoder.decode(memory, pc)?
760 };
761 let cycles = self.instruction_cycle_func()(instruction);
762 self.add_cycles(cycles)?;
763 execute(instruction, self)
764 }
765}
766
767pub struct DefaultMachineBuilder<Inner> {
768 inner: Inner,
769 instruction_cycle_func: Box<InstructionCycleFunc>,
770 debugger: Option<Box<dyn Debugger<Inner>>>,
771 syscalls: Vec<Box<dyn Syscalls<Inner>>>,
772 pause: Pause,
773}
774
775impl<Inner> DefaultMachineBuilder<Inner> {
776 pub fn new(inner: Inner) -> Self {
777 Self {
778 inner,
779 instruction_cycle_func: Box::new(|_| 0),
780 debugger: None,
781 syscalls: vec![],
782 pause: Pause::new(),
783 }
784 }
785
786 pub fn instruction_cycle_func(
787 mut self,
788 instruction_cycle_func: Box<InstructionCycleFunc>,
789 ) -> Self {
790 self.instruction_cycle_func = instruction_cycle_func;
791 self
792 }
793
794 pub fn syscall(mut self, syscall: Box<dyn Syscalls<Inner>>) -> Self {
795 self.syscalls.push(syscall);
796 self
797 }
798
799 pub fn pause(mut self, pause: Pause) -> Self {
800 self.pause = pause;
801 self
802 }
803
804 pub fn debugger(mut self, debugger: Box<dyn Debugger<Inner>>) -> Self {
805 self.debugger = Some(debugger);
806 self
807 }
808
809 pub fn build(self) -> DefaultMachine<Inner> {
810 DefaultMachine {
811 inner: self.inner,
812 pause: self.pause,
813 instruction_cycle_func: self.instruction_cycle_func,
814 debugger: self.debugger,
815 syscalls: self.syscalls,
816 exit_code: 0,
817 }
818 }
819}
820
821#[derive(Clone, Default)]
822pub struct Pause {
823 s: Arc<AtomicU8>,
824}
825
826impl Pause {
827 pub fn new() -> Self {
828 Self {
829 s: Arc::new(AtomicU8::new(0)),
830 }
831 }
832
833 pub fn interrupt(&self) {
834 self.s.store(1, Ordering::SeqCst);
835 }
836
837 pub fn has_interrupted(&self) -> bool {
838 self.s.load(Ordering::SeqCst) != 0
839 }
840
841 pub fn get_raw_ptr(&self) -> *mut u8 {
842 &*self.s as *const _ as *mut u8
843 }
844
845 pub fn free(&mut self) {
846 self.s.store(0, Ordering::SeqCst);
847 }
848}
849
850pub struct FlattenedArgsReader<'a, M: Memory> {
851 memory: &'a mut M,
852 argc: M::REG,
853 argv: M::REG,
854 cidx: M::REG,
855}
856impl<'a, M: Memory> FlattenedArgsReader<'a, M> {
857 pub fn new(memory: &'a mut M, argc: M::REG, argv: M::REG) -> Self {
858 Self {
859 memory,
860 argc,
861 argv,
862 cidx: M::REG::zero(),
863 }
864 }
865}
866impl<'a, M: Memory> Iterator for FlattenedArgsReader<'a, M> {
867 type Item = Result<Bytes, Error>;
868 fn next(&mut self) -> Option<Self::Item> {
869 if self.cidx.ge(&self.argc).to_u8() == 1 {
870 return None;
871 }
872 let addr = match M::REG::BITS {
873 32 => self.memory.load32(&self.argv),
874 64 => self.memory.load64(&self.argv),
875 _ => unreachable!(),
876 };
877 if let Err(err) = addr {
878 return Some(Err(err));
879 };
880 let addr = addr.unwrap();
881 let cstr = load_c_string_byte_by_byte(self.memory, &addr);
882 if let Err(err) = cstr {
883 return Some(Err(err));
884 };
885 let cstr = cstr.unwrap();
886 self.cidx = self.cidx.overflowing_add(&M::REG::from_u8(1));
887 self.argv = self
888 .argv
889 .overflowing_add(&M::REG::from_u8(M::REG::BITS / 8));
890 Some(Ok(cstr))
891 }
892}
893impl<'a, M: Memory> ExactSizeIterator for FlattenedArgsReader<'a, M> {
894 fn len(&self) -> usize {
895 self.argc.to_u64() as usize
896 }
897}
898
899#[cfg(test)]
900mod tests {
901 use std::sync::atomic::AtomicU8;
902
903 #[test]
904 fn test_atomicu8() {
905 assert_eq!(std::mem::size_of::<AtomicU8>(), 1);
908 }
909}