1use std::{ffi::c_void, sync::Arc};
2
3use crate::{
4 assembly::Assembly,
5 bindings::{mono_runtime_invoke, MonoMethod, MonoObject},
6 class::Class,
7 domain::Domain,
8 image::Image,
9 object::Object,
10 void::AsRawVoid,
11 MonoResult,
12};
13
14#[derive(Clone, Debug)]
15pub struct Arguments {
16 pub args: Vec<*mut c_void>,
17}
18
19#[derive(Clone, Debug)]
20pub struct ClassMethod {
21 pub mono_ptr: *mut MonoMethod,
22 pub assembly: Arc<Assembly>,
23 pub class: Arc<Class>,
24 pub domain: Arc<Domain>,
25 pub image: Arc<Image>,
26}
27
28#[derive(Clone, Debug)]
29pub struct ObjectMethod {
30 pub mono_ptr: *mut MonoMethod,
31 pub assembly: Arc<Assembly>,
32 pub class: Arc<Class>,
33 pub domain: Arc<Domain>,
34 pub image: Arc<Image>,
35 pub object: Arc<Object>,
36}
37
38impl ObjectMethod {
39 pub fn invoke(&self, args: Arguments) -> MonoResult<Object> {
40 let mono_result = unsafe {
41 mono_runtime_invoke(
42 self.mono_ptr,
43 self.object.mono_ptr as *mut c_void,
44 args.as_raw_void() as *mut *mut c_void,
45 std::ptr::null_mut(),
46 )
47 };
48 if mono_result.is_null() {
49 return Err("Method returned null".into());
50 }
51
52 let result = Object {
53 mono_ptr: mono_result as *mut MonoObject,
54 assembly: self.assembly.clone(),
55 class: self.class.clone(),
56 domain: self.domain.clone(),
57 image: self.image.clone(),
58 };
59
60 Ok(result)
61 }
62}
63
64#[derive(Clone, Debug)]
65pub struct StaticMethod {
66 pub mono_ptr: *mut MonoMethod,
67 pub assembly: Arc<Assembly>,
68 pub class: Arc<Class>,
69 pub domain: Arc<Domain>,
70 pub image: Arc<Image>,
71}
72
73impl Arguments {
74 pub fn new() -> Arguments {
75 Arguments { args: Vec::new() }
76 }
77
78 pub fn add<T>(&mut self, arg: T)
79 where
80 T: AsRawVoid,
81 {
82 self.args.push(arg.as_raw_void());
83 }
84}
85
86impl AsRawVoid for ClassMethod {
87 fn as_raw_void(self) -> *mut c_void {
88 self.mono_ptr as *mut c_void
89 }
90}
91
92impl AsRawVoid for ObjectMethod {
93 fn as_raw_void(self) -> *mut c_void {
94 self.mono_ptr as *mut c_void
95 }
96}
97
98impl AsRawVoid for StaticMethod {
99 fn as_raw_void(self) -> *mut c_void {
100 self.mono_ptr as *mut c_void
101 }
102}
103
104impl AsRawVoid for Arguments {
105 fn as_raw_void(mut self) -> *mut c_void {
106 self.args.as_mut_ptr() as *mut c_void
107 }
108}