Skip to content

Commit

Permalink
Fix #207
Browse files Browse the repository at this point in the history
  • Loading branch information
pardeike committed Jan 26, 2020
1 parent 150ca85 commit d3c7a06
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 11 deletions.
9 changes: 7 additions & 2 deletions Harmony/Internal/CodeTranspiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,16 @@ internal static IEnumerable ConvertToOurInstructions(IEnumerable instructions, T
}
}

static bool IsCodeInstructionsParameter(Type type)
{
return type.IsGenericType && type.GetGenericTypeDefinition().Name.StartsWith("IEnumerable", StringComparison.Ordinal);
}

internal static IEnumerable ConvertToGeneralInstructions(MethodInfo transpiler, IEnumerable enumerable, out Dictionary<object, Dictionary<string, object>> unassignedValues)
{
var type = transpiler.GetParameters()
.Select(p => p.ParameterType)
.FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition().Name.StartsWith("IEnumerable", StringComparison.Ordinal));
.FirstOrDefault(t => IsCodeInstructionsParameter(t));
return ConvertInstructionsAndUnassignedValues(type, enumerable, out unassignedValues);
}

Expand All @@ -208,7 +213,7 @@ internal static List<object> GetTranspilerCallParameters(ILGenerator generator,
parameter.Add(generator);
else if (type.IsAssignableFrom(typeof(MethodBase)))
parameter.Add(method);
else
else if (IsCodeInstructionsParameter(type))
parameter.Add(instructions);
});
return parameter;
Expand Down
23 changes: 14 additions & 9 deletions Harmony/Internal/MethodCopier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,18 @@ internal MethodBodyReader(MethodBase method, ILGenerator generator)

var body = method.GetMethodBody();
if (body == null)
throw new ArgumentException($"Method {method.FullDescription()} has no body");

var bytes = body.GetILAsByteArray();
if (bytes == null)
throw new ArgumentException($"Can not get IL bytes of method {method.FullDescription()}");
ilBytes = new ByteBuffer(bytes);
ilInstructions = new List<ILInstruction>((bytes.Length + 1) / 2);
{
ilBytes = new ByteBuffer(new byte[0]);
ilInstructions = new List<ILInstruction>();
}
else
{
var bytes = body.GetILAsByteArray();
if (bytes == null)
throw new ArgumentException("Can not get IL bytes of method " + method.FullDescription());
ilBytes = new ByteBuffer(bytes);
ilInstructions = new List<ILInstruction>((bytes.Length + 1) / 2);
}

var type = method.DeclaringType;

Expand All @@ -93,8 +98,8 @@ internal MethodBodyReader(MethodBase method, ILGenerator generator)
this_parameter = new ThisParameter(method);
parameters = method.GetParameters();

localVariables = body.LocalVariables?.ToList() ?? new List<LocalVariableInfo>();
exceptions = body.ExceptionHandlingClauses;
localVariables = body?.LocalVariables?.ToList() ?? new List<LocalVariableInfo>();
exceptions = body?.ExceptionHandlingClauses ?? new List<ExceptionHandlingClause>();
}

internal void ReadInstructions()
Expand Down
9 changes: 9 additions & 0 deletions Harmony/Internal/MethodPatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,9 @@ static bool AddPrefixes(ILGenerator il, MethodBase original, List<MethodInfo> pr
var canHaveJump = false;
prefixes.ForEach(fix =>
{
if (original.GetMethodBody() == null)
throw new Exception("Methods without body cannot have prefixes. Use a transpiler instead.");
EmitCallParameter(il, original, fix, variables, false);
Emitter.Emit(il, OpCodes.Call, fix);
Expand All @@ -500,6 +503,9 @@ static void AddPostfixes(ILGenerator il, MethodBase original, List<MethodInfo> p
.Where(fix => passthroughPatches == (fix.ReturnType != typeof(void)))
.Do(fix =>
{
if (original.GetMethodBody() == null)
throw new Exception("Methods without body cannot have postfixes. Use a transpiler instead.");
EmitCallParameter(il, original, fix, variables, true);
Emitter.Emit(il, OpCodes.Call, fix);
Expand All @@ -524,6 +530,9 @@ static bool AddFinalizers(ILGenerator il, MethodBase original, List<MethodInfo>
finalizers
.Do(fix =>
{
if (original.GetMethodBody() == null)
throw new Exception("Methods without body cannot have finalizers. Use a transpiler instead.");
if (catchExceptions)
Emitter.MarkBlockBefore(il, new ExceptionBlock(ExceptionBlockType.BeginExceptionBlock), out var label);
Expand Down

0 comments on commit d3c7a06

Please sign in to comment.