Skip to content

Commit

Permalink
fixes #445
Browse files Browse the repository at this point in the history
  • Loading branch information
pardeike committed Jan 5, 2022
1 parent cee4ece commit 220ef9e
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 17 deletions.
12 changes: 6 additions & 6 deletions Harmony/Internal/MethodPatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ internal static DynamicMethodDefinition CreateDynamicMethod(MethodBase original,
if (original is null) throw new ArgumentNullException(nameof(original));
var useStructReturnBuffer = StructReturnBuffer.NeedsFix(original);

var patchName = $"{original.DeclaringType?.FullName}.{original.Name}{suffix}";
var patchName = $"{original.DeclaringType?.FullName ?? "GLOBALTYPE"}.{original.Name}{suffix}";
patchName = patchName.Replace("<>", "");

var parameters = original.GetParameters();
Expand Down Expand Up @@ -283,7 +283,7 @@ internal static DynamicMethodDefinition CreateDynamicMethod(MethodBase original,
if (parameterTypes.Count == method.Definition.Parameters.Count)
for (var i = 0; i < parameterTypes.Count; i++)
parameterStrings[i] += $" {method.Definition.Parameters[i].Name}";
FileLog.Log($"### Replacement: static {returnType.FullDescription()} {original.DeclaringType.FullName}::{patchName}({parameterStrings.Join()})");
FileLog.Log($"### Replacement: static {returnType.FullDescription()} {original.DeclaringType?.FullName ?? "GLOBALTYPE"}::{patchName}({parameterStrings.Join()})");
}

return method;
Expand Down Expand Up @@ -510,13 +510,13 @@ void EmitCallParameter(MethodInfo patch, Dictionary<string, LocalBuilder> variab
// field access by index only works for declared fields
fieldInfo = AccessTools.DeclaredField(original.DeclaringType, int.Parse(fieldName));
if (fieldInfo is null)
throw new ArgumentException($"No field found at given index in class {original.DeclaringType.AssemblyQualifiedName}", fieldName);
throw new ArgumentException($"No field found at given index in class {original.DeclaringType?.AssemblyQualifiedName ?? "null"}", fieldName);
}
else
{
fieldInfo = AccessTools.Field(original.DeclaringType, fieldName);
if (fieldInfo is null)
throw new ArgumentException($"No such field defined in class {original.DeclaringType.AssemblyQualifiedName}", fieldName);
throw new ArgumentException($"No such field defined in class {original.DeclaringType?.AssemblyQualifiedName ?? "null"}", fieldName);
}

if (fieldInfo.IsStatic)
Expand All @@ -533,7 +533,7 @@ void EmitCallParameter(MethodInfo patch, Dictionary<string, LocalBuilder> variab
if (patchParam.Name == STATE_VAR)
{
var ldlocCode = patchParam.ParameterType.IsByRef ? OpCodes.Ldloca : OpCodes.Ldloc;
if (variables.TryGetValue(patch.DeclaringType.AssemblyQualifiedName, out var stateVar))
if (variables.TryGetValue(patch.DeclaringType?.AssemblyQualifiedName ?? "null", out var stateVar))
emitter.Emit(ldlocCode, stateVar);
else
emitter.Emit(OpCodes.Ldnull);
Expand Down Expand Up @@ -606,7 +606,7 @@ void EmitCallParameter(MethodInfo patch, Dictionary<string, LocalBuilder> variab
else
{
emitter.Emit(OpCodes.Ldarg_0);
if (originalType.IsValueType)
if (originalType != null && originalType.IsValueType)
{
emitter.Emit(OpCodes.Ldobj, originalType);
emitter.Emit(OpCodes.Box, originalType);
Expand Down
33 changes: 22 additions & 11 deletions Harmony/Tools/AccessTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,8 @@ public static T GetDeclaredMember<T>(this T member) where T : MemberInfo
return member;

var metaToken = member.MetadataToken;
foreach (var other in member.DeclaringType.GetMembers(all))
var members = member.DeclaringType?.GetMembers(all) ?? new MemberInfo[0];
foreach (var other in members)
if (other.MetadataToken == metaToken)
return (T)other;

Expand Down Expand Up @@ -583,7 +584,7 @@ public static List<ConstructorInfo> GetDeclaredConstructors(Type type, bool? sea
{
if (Harmony.DEBUG)
FileLog.Log("AccessTools.GetDeclaredConstructors: type is null");
return null;
return new List<ConstructorInfo>();
}
var flags = allDeclared;
if (searchForStatic.HasValue)
Expand All @@ -601,7 +602,7 @@ public static List<MethodInfo> GetDeclaredMethods(Type type)
{
if (Harmony.DEBUG)
FileLog.Log("AccessTools.GetDeclaredMethods: type is null");
return null;
return new List<MethodInfo>();
}
return type.GetMethods(allDeclared).ToList();
}
Expand All @@ -616,7 +617,7 @@ public static List<PropertyInfo> GetDeclaredProperties(Type type)
{
if (Harmony.DEBUG)
FileLog.Log("AccessTools.GetDeclaredProperties: type is null");
return null;
return new List<PropertyInfo>();
}
return type.GetProperties(allDeclared).ToList();
}
Expand All @@ -631,7 +632,7 @@ public static List<FieldInfo> GetDeclaredFields(Type type)
{
if (Harmony.DEBUG)
FileLog.Log("AccessTools.GetDeclaredFields: type is null");
return null;
return new List<FieldInfo>();
}
return type.GetFields(allDeclared).ToList();
}
Expand Down Expand Up @@ -1468,7 +1469,7 @@ public static DelegateType MethodDelegate<DelegateType>(MethodInfo method, objec
}

var declaringType = method.DeclaringType;
if (declaringType.IsInterface && !virtualCall)
if (declaringType != null && declaringType.IsInterface && !virtualCall)
{
throw new ArgumentException("Interface methods must be called virtually");
}
Expand All @@ -1487,15 +1488,15 @@ public static DelegateType MethodDelegate<DelegateType>(MethodInfo method, objec
var delegateInstanceType = delegateParameters[0].ParameterType;
// Exceptional case: delegate struct instance type cannot be created from an interface method.
// This case is handled in the "non-virtual call" case, using the struct method and the matching delegate instance type.
if (declaringType.IsInterface && delegateInstanceType.IsValueType)
if (declaringType != null && declaringType.IsInterface && delegateInstanceType.IsValueType)
{
var interfaceMapping = delegateInstanceType.GetInterfaceMap(declaringType);
method = interfaceMapping.TargetMethods[Array.IndexOf(interfaceMapping.InterfaceMethods, method)];
declaringType = delegateInstanceType;
}

// ... that virtually calls ...
if (virtualCall)
if (declaringType != null && virtualCall)
{
// ... an interface method
// If method is already an interface method, just create a delegate from it directly.
Expand Down Expand Up @@ -1538,7 +1539,7 @@ public static DelegateType MethodDelegate<DelegateType>(MethodInfo method, objec
OwnerType = declaringType
};
var ilGen = dmd.GetILGenerator();
if (declaringType.IsValueType)
if (declaringType != null && declaringType.IsValueType)
ilGen.Emit(OpCodes.Ldarga_S, 0);
else
ilGen.Emit(OpCodes.Ldarg_0);
Expand All @@ -1558,7 +1559,7 @@ public static DelegateType MethodDelegate<DelegateType>(MethodInfo method, objec
// Closed instance method delegate that non-virtually calls
// It's possible to create a delegate to a derived class method bound to a base class object,
// but this has undefined behavior, so disallow it.
if (!declaringType.IsInstanceOfType(instance))
if (declaringType != null && !declaringType.IsInstanceOfType(instance))
{
// Following should throw an ArgumentException with the proper message string.
_ = Delegate.CreateDelegate(typeof(DelegateType), instance, method);
Expand Down Expand Up @@ -1870,6 +1871,8 @@ public static object MakeDeepCopy(object source, Type resultType, Func<string, T
///
public static bool IsStruct(Type type)
{
if (type == null)
return false;
return type.IsValueType && !IsValue(type) && !IsVoid(type);
}

Expand All @@ -1879,6 +1882,8 @@ public static bool IsStruct(Type type)
///
public static bool IsClass(Type type)
{
if (type == null)
return false;
return !type.IsValueType;
}

Expand All @@ -1888,6 +1893,8 @@ public static bool IsClass(Type type)
///
public static bool IsValue(Type type)
{
if (type == null)
return false;
return type.IsPrimitive || type.IsEnum;
}

Expand All @@ -1897,6 +1904,8 @@ public static bool IsValue(Type type)
///
public static bool IsInteger(Type type)
{
if (type == null)
return false;
switch (Type.GetTypeCode(type))
{
case TypeCode.Byte:
Expand All @@ -1919,6 +1928,8 @@ public static bool IsInteger(Type type)
///
public static bool IsFloatingPoint(Type type)
{
if (type == null)
return false;
switch (Type.GetTypeCode(type))
{
case TypeCode.Decimal:
Expand Down Expand Up @@ -1995,7 +2006,7 @@ public static bool IsStatic(MemberInfo member)
public static bool IsStatic(Type type)
{
if (type is null)
throw new ArgumentNullException(nameof(type));
return false;
return type.IsAbstract && type.IsSealed;
}

Expand Down

0 comments on commit 220ef9e

Please sign in to comment.