1pub mod mainloop;
2pub mod realmexit;
3pub mod rmihandle;
4pub mod rsihandle;
5
6pub use crate::rmi::error::Error;
7pub use crate::rsi;
8pub use mainloop::Mainloop;
9pub use rmihandle::RmiHandle;
10pub use rsihandle::RsiHandle;
11
12extern crate alloc;
13use alloc::vec::Vec;
14
15#[macro_export]
16macro_rules! listen {
17 ($eventloop:expr, $code:expr, $handler:expr) => {{
18 $eventloop.add_event_handler($code.into(), alloc::boxed::Box::new($handler))
19 }};
20}
21
22pub type Command = usize;
23
24#[derive(Clone)]
25pub struct Context {
26 pub cmd: Command,
27 pub arg: Vec<usize>,
28 pub ret: Vec<usize>,
29 pub sve_hint: bool,
30 pub x4: u64,
31}
32
33impl Context {
34 pub fn new(cmd: Command) -> Context {
35 Context {
36 cmd,
37 arg: Vec::new(),
38 ret: Vec::new(),
39 sve_hint: false,
40 x4: 0,
41 }
42 }
43
44 pub fn init_arg(&mut self, arg: &[usize]) {
45 self.arg.clear();
46 self.arg.extend_from_slice(arg);
47 }
48
49 pub fn init_ret(&mut self, ret: &[usize]) {
50 self.ret.clear();
51 self.ret.extend_from_slice(ret);
52 }
53
54 pub fn resize_ret(&mut self, new_len: usize) {
55 self.ret.clear();
56 self.ret.resize(new_len, 0);
57 }
58
59 pub fn arg_slice(&self) -> &[usize] {
60 &self.arg[..]
61 }
62
63 pub fn ret_slice(&self) -> &[usize] {
64 &self.ret[..]
65 }
66
67 pub fn cmd(&self) -> Command {
68 self.cmd
69 }
70
71 pub fn do_rsi<F>(&mut self, mut handler: F)
72 where
73 F: FnMut(&[usize], &mut [usize]) -> Result<(), Error>,
74 {
75 self.ret[0] = rsi::SUCCESS;
76
77 #[cfg(feature = "stat")]
78 {
79 trace!("let's get STATS.lock() with cmd {}", rsi::to_str(self.cmd));
80 crate::stat::STATS.lock().measure(self.cmd, || {
81 if let Err(code) = handler(&self.arg[..], &mut self.ret[..]) {
82 error!("rsi handler returns error:{:?}", code);
83 self.ret[0] = code.into();
84 }
85 });
86 }
87 #[cfg(not(feature = "stat"))]
88 {
89 if let Err(code) = handler(&self.arg[..], &mut self.ret[..]) {
90 error!("rsi handler returns error:{:?}", code);
91 self.ret[0] = code.into();
92 }
93 }
94
95 trace!(
96 "RSI: {0: <20} {1:X?} > {2:X?}",
97 rsi::to_str(self.cmd),
98 &self.arg,
99 &self.ret
100 );
101 self.arg.clear();
102 self.arg.extend_from_slice(&self.ret[..]);
103 }
104}
105
106impl Default for Context {
107 fn default() -> Context {
108 Context::new(0)
109 }
110}