Skip to content

Commit e04ee79

Browse files
committed
Rework unsafe_impl_type macros
1 parent dba9e8f commit e04ee79

File tree

9 files changed

+481
-148
lines changed

9 files changed

+481
-148
lines changed

examples/custom_type.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub struct Vector3 {
1616
y: f32,
1717
z: f32,
1818
}
19-
unsafe_impl_value_type!(Vector3, "UnityEngine", "Vector3");
19+
unsafe_impl_value_type!(in quest_hook::libil2cpp for Vector3 => UnityEngine.Vector3);
2020

2121
#[hook("UnityEngine", "RigidBody", "set_position")]
2222
fn set_position(this: &mut Il2CppObject, new_position: Vector3) {

libil2cpp/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ mod string;
102102
mod ty;
103103
mod typecheck;
104104

105+
#[doc(inline)]
106+
pub use quest_hook_proc_macros::{unsafe_impl_reference_type, unsafe_impl_value_type};
107+
105108
pub use array::Il2CppArray;
106109
pub use class::{FindMethodError, Il2CppClass};
107110
pub use exception::Il2CppException;

libil2cpp/src/method_info.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ impl MethodInfo {
8181
// }
8282

8383
/// [`Il2CppReflectionMethod`] which represents the method
84-
pub fn reflection_object(&self) -> &Il2CppReflectionMethod {
85-
unsafe { Il2CppReflectionMethod::wrap(raw::method_get_object(self.raw(), None)) }
84+
pub fn reflection_object(&self) -> &'static mut Il2CppReflectionMethod {
85+
unsafe { Il2CppReflectionMethod::wrap_mut(raw::method_get_object(self.raw(), None)) }
8686
}
8787

8888
/// Name of the method

libil2cpp/src/raw/functions.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ il2cpp_functions! {
2323
pub fn class_get_type(class: &Il2CppClass) -> &'static Il2CppType;
2424
pub fn field_set_value(obj: &mut Il2CppObject, field: &FieldInfo, value: *const c_void);
2525
pub fn field_get_value(obj: &mut Il2CppObject, field: &FieldInfo, value: *mut c_void);
26-
pub fn method_get_object(method: &MethodInfo, refclass: Option<&Il2CppClass>) -> &'static Il2CppReflectionMethod;
26+
pub fn method_get_object(method: &MethodInfo, refclass: Option<&Il2CppClass>) -> &'static mut Il2CppReflectionMethod;
2727
pub fn method_get_from_reflection(method: &Il2CppReflectionMethod) -> &'static MethodInfo;
2828
pub fn method_is_generic(method: &MethodInfo) -> bool;
2929
pub fn array_new(element_class: &Il2CppClass, length: usize) -> Option<&'static mut Il2CppArray>;
3030
pub fn array_class_get(element_class: &Il2CppClass, rank: u32, bounded: bool) -> &'static Il2CppClass;
3131
pub fn type_get_name(ty: &Il2CppType) -> *const c_char;
32-
pub fn type_get_object(ty: &Il2CppType) -> &'static Il2CppReflectionType;
32+
pub fn type_get_object(ty: &Il2CppType) -> &'static mut Il2CppReflectionType;
3333
pub fn runtime_invoke(method: &MethodInfo, instance: *mut c_void, params: *mut *mut c_void, exception: &mut Option<&mut Il2CppException>) -> Option<&'static mut Il2CppObject>;
3434
pub fn string_new_len(s: *const char, len: u32) -> &'static mut Il2CppString;
3535
pub fn raise_exception(exc: &Il2CppException) -> !;

libil2cpp/src/ty.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ impl Il2CppType {
4242
}
4343

4444
/// [`Il2CppReflectionType`] which represents the type
45-
pub fn reflection_object(&self) -> &Il2CppReflectionType {
46-
unsafe { Il2CppReflectionType::wrap(raw::type_get_object(self.raw())) }
45+
pub fn reflection_object(&self) -> &'static mut Il2CppReflectionType {
46+
unsafe { Il2CppReflectionType::wrap_mut(raw::type_get_object(self.raw())) }
4747
}
4848
}
4949

libil2cpp/src/typecheck/ty.rs

+18-141
Original file line numberDiff line numberDiff line change
@@ -61,144 +61,21 @@ pub unsafe trait Type: 'static {
6161
}
6262
}
6363

64-
/// Implements the [`Type`] trait for a C# reference type
65-
///
66-
/// # Safety
67-
/// The Rust and C# types must be ABI-compatible and the C# type must be a
68-
/// reference type
69-
#[macro_export]
70-
macro_rules! unsafe_impl_reference_type {
71-
($type:ty, $namespace:literal, $class:literal) => {
72-
unsafe impl $crate::Type for $type {
73-
type Held<'a> = ::std::option::Option<&'a mut $type>;
74-
75-
const NAMESPACE: &'static str = $namespace;
76-
const CLASS_NAME: &'static str = $class;
77-
78-
fn matches_reference_argument(ty: &$crate::Il2CppType) -> bool {
79-
ty.class()
80-
.is_assignable_from(<Self as $crate::Type>::class())
81-
}
82-
fn matches_value_argument(_: &$crate::Il2CppType) -> bool {
83-
false
84-
}
85-
86-
fn matches_reference_parameter(ty: &$crate::Il2CppType) -> bool {
87-
<Self as $crate::Type>::class().is_assignable_from(ty.class())
88-
}
89-
fn matches_value_parameter(_: &$crate::Il2CppType) -> bool {
90-
false
91-
}
92-
}
93-
};
94-
}
95-
96-
/// Implements the [`Type`] trait for a C# value type
97-
///
98-
/// # Safety
99-
/// The Rust and C# types must be ABI-compatible and the C# type must be a value
100-
/// type
101-
#[macro_export]
102-
macro_rules! unsafe_impl_value_type {
103-
($type:ty, $namespace:literal, $class:literal) => {
104-
unsafe impl $crate::Type for $type {
105-
type Held<'a> = $type;
106-
107-
const NAMESPACE: &'static str = $namespace;
108-
const CLASS_NAME: &'static str = $class;
109-
110-
fn matches_value_argument(ty: &$crate::Il2CppType) -> bool {
111-
!ty.is_ref()
112-
&& ty
113-
.class()
114-
.is_assignable_from(<Self as $crate::Type>::class())
115-
}
116-
fn matches_reference_argument(ty: &$crate::Il2CppType) -> bool {
117-
ty.is_ref()
118-
&& ty
119-
.class()
120-
.is_assignable_from(<Self as $crate::Type>::class())
121-
}
122-
123-
fn matches_value_parameter(ty: &$crate::Il2CppType) -> bool {
124-
!ty.is_ref() && <Self as $crate::Type>::class().is_assignable_from(ty.class())
125-
}
126-
fn matches_reference_parameter(ty: &$crate::Il2CppType) -> bool {
127-
ty.is_ref() && <Self as $crate::Type>::class().is_assignable_from(ty.class())
128-
}
129-
}
130-
131-
unsafe impl $crate::Argument for $type {
132-
type Type = Self;
133-
134-
fn matches(ty: &$crate::Il2CppType) -> bool {
135-
<Self as $crate::Type>::matches_value_argument(ty)
136-
}
137-
138-
fn invokable(&mut self) -> *mut ::std::ffi::c_void {
139-
self as *mut Self as *mut ::std::ffi::c_void
140-
}
141-
}
142-
143-
unsafe impl $crate::Parameter for $type {
144-
type Actual = Self;
145-
146-
fn matches(ty: &$crate::Il2CppType) -> bool {
147-
<Self as $crate::Type>::matches_value_parameter(ty)
148-
}
149-
150-
fn from_actual(actual: Self::Actual) -> Self {
151-
actual
152-
}
153-
fn into_actual(self) -> Self::Actual {
154-
self
155-
}
156-
}
157-
158-
unsafe impl $crate::Returned for $type {
159-
type Type = Self;
160-
161-
fn matches(ty: &$crate::Il2CppType) -> bool {
162-
<Self as $crate::Type>::matches_returned(ty)
163-
}
164-
165-
fn from_object(object: Option<&mut $crate::Il2CppObject>) -> Self {
166-
unsafe { $crate::raw::unbox($crate::WrapRaw::raw(object.unwrap())) }
167-
}
168-
}
169-
170-
unsafe impl $crate::Return for $type {
171-
type Actual = Self;
172-
173-
fn matches(ty: &$crate::Il2CppType) -> bool {
174-
<Self as $crate::Type>::matches_return(ty)
175-
}
176-
177-
fn into_actual(self) -> Self::Actual {
178-
self
179-
}
180-
fn from_actual(actual: Self::Actual) -> Self {
181-
actual
182-
}
183-
}
184-
};
185-
}
186-
187-
unsafe_impl_value_type!(u8, "System", "Byte");
188-
unsafe_impl_value_type!(i8, "System", "SByte");
189-
unsafe_impl_value_type!(u16, "System", "UInt16");
190-
unsafe_impl_value_type!(i16, "System", "Int16");
191-
unsafe_impl_value_type!(u32, "System", "UInt32");
192-
unsafe_impl_value_type!(i32, "System", "Int32");
193-
unsafe_impl_value_type!(u64, "System", "UInt64");
194-
unsafe_impl_value_type!(i64, "System", "Int64");
195-
unsafe_impl_value_type!(usize, "System", "UIntPtr");
196-
unsafe_impl_value_type!(isize, "System", "IntPtr");
197-
unsafe_impl_value_type!(f32, "System", "Single");
198-
unsafe_impl_value_type!(f64, "System", "Double");
199-
unsafe_impl_value_type!(bool, "System", "Boolean");
200-
201-
unsafe_impl_reference_type!(Il2CppObject, "System", "Object");
202-
unsafe_impl_reference_type!(Il2CppString, "System", "String");
203-
unsafe_impl_reference_type!(Il2CppReflectionType, "System", "RuntimeType");
204-
unsafe_impl_reference_type!(Il2CppReflectionMethod, "System.Reflection", "MonoMethod");
64+
crate::unsafe_impl_value_type!(in crate for u8 => System.Byte);
65+
crate::unsafe_impl_value_type!(in crate for i8 => System.SByte);
66+
crate::unsafe_impl_value_type!(in crate for u16 => System.UInt16);
67+
crate::unsafe_impl_value_type!(in crate for i16 => System.Int16);
68+
crate::unsafe_impl_value_type!(in crate for u32 => System.UInt32);
69+
crate::unsafe_impl_value_type!(in crate for i32 => System.Int32);
70+
crate::unsafe_impl_value_type!(in crate for u64 => System.UInt64);
71+
crate::unsafe_impl_value_type!(in crate for i64 => System.Int64);
72+
crate::unsafe_impl_value_type!(in crate for usize => System.UIntPtr);
73+
crate::unsafe_impl_value_type!(in crate for isize => System.IntPtr);
74+
crate::unsafe_impl_value_type!(in crate for f32 => System.Single);
75+
crate::unsafe_impl_value_type!(in crate for f64 => System.Double);
76+
crate::unsafe_impl_value_type!(in crate for bool => System.Boolean);
77+
78+
crate::unsafe_impl_reference_type!(in crate for Il2CppObject => System.Object);
79+
crate::unsafe_impl_reference_type!(in crate for Il2CppString => System.String);
80+
crate::unsafe_impl_reference_type!(in crate for Il2CppReflectionType => System.RuntimeType);
81+
crate::unsafe_impl_reference_type!(in crate for Il2CppReflectionMethod => System.Reflection.MonoMethod);

0 commit comments

Comments
 (0)