-
Notifications
You must be signed in to change notification settings - Fork 8
Open
Description
Method::invoke
Implementation works fine only with value types like integers. Using Object
in method signature breaks it and causing crashes.
Lines 207 to 215 in fac74e2
pub fn invoke(&self, object: Option<Object>, args: Args) -> Result<Option<Object>, Exception> { | |
//convert object to invoke on to a pointer. | |
let obj_ptr = object.map_or(core::ptr::null_mut(), |obj| obj.get_ptr()); | |
let mut expect: *mut MonoException = null_mut(); | |
//convert argument types | |
let mut args = <Args as InteropSend>::get_mono_rep(args); | |
let mut params = <<Args as InteropSend>::TargetType as TupleToPtrs>::get_ptrs( | |
std::ptr::addr_of_mut!(args), | |
); |
Actual problem is in get_ptrs
method
Lines 213 to 215 in fac74e2
let mut params = <<Args as InteropSend>::TargetType as TupleToPtrs>::get_ptrs( | |
std::ptr::addr_of_mut!(args), | |
); |
args
is the tuple of pointers and values.
But get_ptrs
implementations treat all args
members like values, creating pointers to each:
wrapped_mono/src/tupleutilis.rs
Lines 32 to 40 in fac74e2
impl<A, B, C> TupleToPtrs for (A, B, C) { | |
type Res = [*mut c_void; 3]; | |
fn get_ptrs(base_ptr: *mut Self) -> Self::Res { | |
let a = base_ptr as usize; | |
let b = a + std::mem::size_of::<A>(); | |
let c = b + std::mem::size_of::<B>(); | |
[a as VoidPtr, b as VoidPtr, c as VoidPtr] | |
} | |
} |
MonoObject*
pointers must be stored by value, not by reference to pointer.
I think this is easy to reproduce using any method that takes Object
by pointer value:
let object: Object = /*...*/ ;
let method: Method<(Object, )> = /*...*/ ;
// This works fine
let mut params = [object.get_ptr()];
wrapped_mono::binds::mono_runtime_invoke(method.get_ptr(), 0 as _, params.as_mut_ptr() as _, 0 as _);
// This crashes
method.invoke(None, (object, ));
Metadata
Metadata
Assignees
Labels
No labels