Skip to content

Commit

Permalink
Merge branch 'BepInEx:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
CamelCaseName authored Aug 15, 2023
2 parents f6f1739 + f3533f9 commit af44ea4
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 14 deletions.
22 changes: 21 additions & 1 deletion Il2CppInterop.Generator/Passes/Pass80UnstripMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ private static PropertyDefinition GetOrCreateProperty(MethodDefinition unityMeth
unityMethod.DeclaringType.Properties.Single(
it => it.SetMethod == unityMethod || it.GetMethod == unityMethod);
var newProperty = newMethod.DeclaringType.Properties.SingleOrDefault(it =>
it.Name == unityProperty.Name && it.Parameters.Count == unityProperty.Parameters.Count);
it.Name == unityProperty.Name && it.Parameters.Count == unityProperty.Parameters.Count &&
it.Parameters.SequenceEqual(unityProperty.Parameters, new TypeComparer()));
if (newProperty == null)
{
newProperty = new PropertyDefinition(unityProperty.Name, PropertyAttributes.None,
Expand Down Expand Up @@ -228,4 +229,23 @@ private static PropertyDefinition GetOrCreateProperty(MethodDefinition unityMeth

return newType;
}

//Stolen from: https://github.com/kremnev8/Il2CppInterop/blob/2c4a31f95f8aa6afe910aca0f8044efb80259d20/Il2CppInterop.Generator/Passes/Pass11ComputeTypeSpecifics.cs#L223
internal sealed class TypeComparer : IEqualityComparer<ParameterDefinition>
{
public bool Equals(ParameterDefinition x, ParameterDefinition y)
{
if (x == null)
return y == null;
if (y == null)
return false;

return x.ParameterType.FullName.Equals(y.ParameterType.FullName);
}

public int GetHashCode(ParameterDefinition obj)
{
return obj.ParameterType.FullName.GetHashCode();
}
}
}
8 changes: 6 additions & 2 deletions Il2CppInterop.HarmonySupport/HarmonyBackendComponent.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using HarmonyLib.Public.Patching;
using Il2CppInterop.Common.Host;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;

namespace Il2CppInterop.HarmonySupport;

Expand All @@ -21,7 +22,10 @@ internal class HarmonySupportComponent : IHostComponent

private static void TryResolve(object sender, PatchManager.PatcherResolverEventArgs args)
{
if (args.Original.DeclaringType?.IsSubclassOf(typeof(Il2CppObjectBase)) != true)
var declaringType = args.Original.DeclaringType;
if (declaringType == null) return;
if (Il2CppType.From(declaringType, false) == null ||
ClassInjector.IsManagedTypeInjected(declaringType))
{
return;
}
Expand Down
8 changes: 5 additions & 3 deletions Il2CppInterop.Runtime/DelegateSupport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ internal static Type GetOrCreateDelegateType(MethodSignature signature, MethodIn

private static Type CreateDelegateType(MethodInfo managedMethodInner, MethodSignature signature)
{
var newType = ModuleBuilder.DefineType(
"Il2CppToManagedDelegate_" + managedMethodInner.DeclaringType.FullName + "_" + signature.GetHashCode() + (signature.HasThis ? "HasThis" : "") +
(signature.ConstructedFromNative ? "FromNative" : ""), TypeAttributes.Sealed | TypeAttributes.Public,
var typeName = "Il2CppToManagedDelegate_" + managedMethodInner.DeclaringType + "_" + signature.GetHashCode() +
(signature.HasThis ? "HasThis" : "") +
(signature.ConstructedFromNative ? "FromNative" : "");

var newType = ModuleBuilder.DefineType(typeName, TypeAttributes.Sealed | TypeAttributes.Public,
typeof(MulticastDelegate));
newType.SetCustomAttribute(new CustomAttributeBuilder(
typeof(UnmanagedFunctionPointerAttribute).GetConstructor(new[] { typeof(CallingConvention) })!,
Expand Down
38 changes: 31 additions & 7 deletions Il2CppInterop.Runtime/Injection/ClassInjector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,13 @@ public static bool IsTypeRegisteredInIl2Cpp(Type type)
var currentPointer = Il2CppClassPointerStore.GetNativeClassPointer(type);
if (currentPointer != IntPtr.Zero)
return true;
if (IsManagedTypeInjected(type)) return true;

return false;
}

internal static bool IsManagedTypeInjected(Type type)
{
lock (InjectedTypes)
{
if (InjectedTypes.Contains(type.FullName))
Expand Down Expand Up @@ -305,7 +312,12 @@ public static void RegisterTypeInIl2Cpp(Type type, RegisterTypeOptions options)

methodPointerArray[0] = ConvertStaticMethod(FinalizeDelegate, "Finalize", classPointer);
var finalizeMethod = UnityVersionHandler.Wrap(methodPointerArray[0]);
if (!type.IsAbstract) methodPointerArray[1] = ConvertStaticMethod(CreateEmptyCtor(type, fieldsToInject), ".ctor", classPointer);
var fieldsToInitialize = type
.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.Where(IsFieldEligible)
.ToArray();

if (!type.IsAbstract) methodPointerArray[1] = ConvertStaticMethod(CreateEmptyCtor(type, fieldsToInitialize), ".ctor", classPointer);
var infos = new Dictionary<(string, int, bool), int>(eligibleMethods.Length);
for (var i = 0; i < eligibleMethods.Length; i++)
{
Expand Down Expand Up @@ -372,6 +384,18 @@ static void FindAbstractMethods(List<INativeMethodInfoStruct> list, INativeClass
}

var abstractV = 0;

INativeMethodInfoStruct HandleAbstractMethod(int position)
{
if (!extendsAbstract) throw new NullReferenceException("VTable method was null even though base type isn't abstract");

var nativeMethodInfoStruct = abstractBaseMethods[abstractV++];

vTablePointer[position].method = nativeMethodInfoStruct.MethodInfoPointer;
vTablePointer[position].methodPtr = nativeMethodInfoStruct.MethodPointer;
return nativeMethodInfoStruct;
}

for (var i = 0; i < baseClassPointer.VtableCount; i++)
{
vTablePointer[i] = baseVTablePointer[i];
Expand All @@ -380,18 +404,18 @@ static void FindAbstractMethods(List<INativeMethodInfoStruct> list, INativeClass

if (baseVTablePointer[i].method == default)
{
if (!extendsAbstract) throw new NullReferenceException("VTable method was null even though base type isn't abstract");

baseMethod = abstractBaseMethods[abstractV++];

vTablePointer[i].method = baseMethod.MethodInfoPointer;
vTablePointer[i].methodPtr = baseMethod.MethodPointer;
baseMethod = HandleAbstractMethod(i);
}
else
{
baseMethod = UnityVersionHandler.Wrap(vTablePointer[i].method);
}

if (baseMethod.Name == IntPtr.Zero)
{
baseMethod = HandleAbstractMethod(i);
}

var methodName = Marshal.PtrToStringAnsi(baseMethod.Name);

if (methodName == "Finalize") // slot number is not static
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public TRefObj Value

public void Set(TRefObj value)
{
*GetPointerToData() = value.Pointer;
*GetPointerToData() = value != null ? value.Pointer : IntPtr.Zero;
}

public static implicit operator TRefObj(Il2CppReferenceField<TRefObj> _this)
Expand Down

0 comments on commit af44ea4

Please sign in to comment.