#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
using System;
using System.Runtime.InteropServices;
namespace SingularityGroup.HotReload.Interop {
//see _MonoMethod struct in class-internals.h
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Auto, Size = 8 + sizeof(long) * 3 + 4)]
internal unsafe struct MonoMethod64 {
[FieldOffset(0)]
public MethodAttributes flags;
[FieldOffset(2)]
public MethodImplAttributes iflags;
[FieldOffset(4)]
public uint token;
[FieldOffset(8)]
public void* klass;
[FieldOffset(8 + sizeof(long))]
public void* signature;
[FieldOffset(8 + sizeof(long) * 2)]
public char* name;
/* this is used by the inlining algorithm */
[FieldOffset(8 + sizeof(long) * 3)]
public MonoMethodFlags monoMethodFlags;
[FieldOffset(8 + sizeof(long) * 3 + 2)]
public short slot;
}
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Auto, Size = 8 + sizeof(int) * 3 + 4)]
internal unsafe struct MonoMethod32 {
[FieldOffset(0)]
public MethodAttributes flags;
[FieldOffset(2)]
public MethodImplAttributes iflags;
[FieldOffset(4)]
public uint token;
[FieldOffset(8)]
public void* klass;
[FieldOffset(8 + sizeof(int))]
public void* signature;
[FieldOffset(8 + sizeof(int) * 2)]
public char* name;
/* this is used by the inlining algorithm */
[FieldOffset(8 + sizeof(int) * 3)]
public MonoMethodFlags monoMethodFlags;
[FieldOffset(8 + sizeof(int) * 3 + 2)]
public short slot;
}
//Corresponds to the bitflags of the _MonoMethod struct
[Flags]
internal enum MonoMethodFlags : ushort {
inline_info = 1 << 0, //:1
inline_failure = 1 << 1, //:1
wrapper_type = 1 << 2, //:5
string_ctor = 1 << 7, //:1
save_lmf = 1 << 8, //:1
dynamic = 1 << 9, //:1 /* created & destroyed during runtime */
sre_method = 1 << 10, //:1 /* created at runtime using Reflection.Emit */
is_generic = 1 << 11, //:1 /* whenever this is a generic method definition */
is_inflated = 1 << 12, //:1 /* whether we're a MonoMethodInflated */
skip_visibility = 1 << 13, //:1 /* whenever to skip JIT visibility checks */
verification_success = 1 << 14, //:1 /* whether this method has been verified successfully.*/
}
[Flags]
internal enum MethodImplAttributes : ushort {
/// Specifies that the method implementation is in Microsoft intermediate language (MSIL).
IL = 0,
/// Specifies that the method is implemented in managed code.
Managed = 0,
/// Specifies that the method implementation is native.
Native = 1,
/// Specifies that the method implementation is in Optimized Intermediate Language (OPTIL).
OPTIL = 2,
/// Specifies flags about code type.
CodeTypeMask = 3,
/// Specifies that the method implementation is provided by the runtime.
Runtime = 3,
/// Specifies whether the method is implemented in managed or unmanaged code.
ManagedMask = 4,
/// Specifies that the method is implemented in unmanaged code.
Unmanaged = 4,
/// Specifies that the method cannot be inlined.
NoInlining = 8,
/// Specifies that the method is not defined.
ForwardRef = 16, // 0x00000010
/// Specifies that the method is single-threaded through the body. Static methods (Shared in Visual Basic) lock on the type, whereas instance methods lock on the instance. You can also use the C# lock statement or the Visual Basic SyncLock statement for this purpose.
Synchronized = 32, // 0x00000020
/// Specifies that the method is not optimized by the just-in-time (JIT) compiler or by native code generation (see Ngen.exe) when debugging possible code generation problems.
NoOptimization = 64, // 0x00000040
/// Specifies that the method signature is exported exactly as declared.
PreserveSig = 128, // 0x00000080
/// Specifies that the method should be inlined wherever possible.
AggressiveInlining = 256, // 0x00000100
/// Specifies an internal call.
InternalCall = 4096, // 0x00001000
/// Specifies a range check value.
MaxMethodImplVal = 65535, // 0x0000FFFF
}
/// Specifies flags for method attributes. These flags are defined in the corhdr.h file.
[Flags]
internal enum MethodAttributes : ushort {
/// Retrieves accessibility information.
MemberAccessMask = 7,
/// Indicates that the member cannot be referenced.
PrivateScope = 0,
/// Indicates that the method is accessible only to the current class.
Private = 1,
/// Indicates that the method is accessible to members of this type and its derived types that are in this assembly only.
FamANDAssem = 2,
/// Indicates that the method is accessible to any class of this assembly.
Assembly = FamANDAssem | Private, // 0x00000003
/// Indicates that the method is accessible only to members of this class and its derived classes.
Family = 4,
/// Indicates that the method is accessible to derived classes anywhere, as well as to any class in the assembly.
FamORAssem = Family | Private, // 0x00000005
/// Indicates that the method is accessible to any object for which this object is in scope.
Public = Family | FamANDAssem, // 0x00000006
/// Indicates that the method is defined on the type; otherwise, it is defined per instance.
Static = 16, // 0x00000010
/// Indicates that the method cannot be overridden.
Final = 32, // 0x00000020
/// Indicates that the method is virtual.
Virtual = 64, // 0x00000040
/// Indicates that the method hides by name and signature; otherwise, by name only.
HideBySig = 128, // 0x00000080
/// Indicates that the method can only be overridden when it is also accessible.
CheckAccessOnOverride = 512, // 0x00000200
/// Retrieves vtable attributes.
VtableLayoutMask = 256, // 0x00000100
/// Indicates that the method will reuse an existing slot in the vtable. This is the default behavior.
ReuseSlot = 0,
/// Indicates that the method always gets a new slot in the vtable.
NewSlot = VtableLayoutMask, // 0x00000100
/// Indicates that the class does not provide an implementation of this method.
Abstract = 1024, // 0x00000400
/// Indicates that the method is special. The name describes how this method is special.
SpecialName = 2048, // 0x00000800
/// Indicates that the method implementation is forwarded through PInvoke (Platform Invocation Services).
PinvokeImpl = 8192, // 0x00002000
/// Indicates that the managed method is exported by thunk to unmanaged code.
UnmanagedExport = 8,
/// Indicates that the common language runtime checks the name encoding.
RTSpecialName = 4096, // 0x00001000
/// Indicates a reserved flag for runtime use only.
ReservedMask = 53248, // 0x0000D000
/// Indicates that the method has security associated with it. Reserved flag for runtime use only.
HasSecurity = 16384, // 0x00004000
/// Indicates that the method calls another method containing security code. Reserved flag for runtime use only.
RequireSecObject = 32768, // 0x00008000
}
}
#endif