Better guessing on the generic operand type

This commit is contained in:
Westin Miller
2017-09-11 20:26:33 -07:00
parent b1145c8926
commit 373c476d2d
4 changed files with 26 additions and 4 deletions

View File

@@ -12,6 +12,6 @@
<rules> <rules>
<logger name="*" minlevel="Info" writeTo="main, console" /> <logger name="*" minlevel="Info" writeTo="main, console" />
<logger name="Chat" minlevel="Info" writeTo="chat" /> <logger name="Chat" minlevel="Info" writeTo="chat" />
<!--<logger name="Torch.Managers.PatchManager.*" minlevel="Trace" writeTo="patch"/>--> <logger name="Torch.Managers.PatchManager.*" minlevel="Trace" writeTo="patch"/>
</rules> </rules>
</nlog> </nlog>

View File

@@ -1,5 +1,7 @@
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection; using System.Reflection;
using System.Reflection.Emit; using System.Reflection.Emit;
using System.Text; using System.Text;
@@ -103,6 +105,9 @@ namespace Torch.Managers.PatchManager.MSIL
/// </summary> /// </summary>
public HashSet<MsilLabel> Labels { get; } = new HashSet<MsilLabel>(); public HashSet<MsilLabel> Labels { get; } = new HashSet<MsilLabel>();
private static readonly ConcurrentDictionary<Type, PropertyInfo> _setterInfoForInlines = new ConcurrentDictionary<Type, PropertyInfo>();
/// <summary> /// <summary>
/// Sets the inline value for this instruction. /// Sets the inline value for this instruction.
/// </summary> /// </summary>
@@ -111,6 +116,23 @@ namespace Torch.Managers.PatchManager.MSIL
/// <returns>This instruction</returns> /// <returns>This instruction</returns>
public MsilInstruction InlineValue<T>(T o) public MsilInstruction InlineValue<T>(T o)
{ {
Type type = typeof(T);
while (type != null)
{
if (!_setterInfoForInlines.TryGetValue(type, out PropertyInfo target))
{
Type genType = typeof(MsilOperandInline<>).MakeGenericType(type);
target = genType.GetProperty(nameof(MsilOperandInline<int>.Value));
_setterInfoForInlines[type] = target;
}
Debug.Assert(target?.DeclaringType != null);
if (target.DeclaringType.IsInstanceOfType(Operand))
{
target.SetValue(Operand, o);
return this;
}
type = type.BaseType;
}
((MsilOperandInline<T>)Operand).Value = o; ((MsilOperandInline<T>)Operand).Value = o;
return this; return this;
} }

View File

@@ -143,7 +143,7 @@ namespace Torch.Managers.PatchManager.Transpile
public string ToHumanMsil() public string ToHumanMsil()
{ {
return string.Join("\n", _instructions.Select(x => $"IL_{x.Offset:X4}: {x.StackChange()} {x}")); return string.Join("\n", _instructions.Select(x => $"IL_{x.Offset:X4}: {x.StackChange():+0;-#} {x}"));
} }
private static readonly Dictionary<short, OpCode> OpCodeLookup; private static readonly Dictionary<short, OpCode> OpCodeLookup;

View File

@@ -16,8 +16,8 @@ namespace Torch.Managers.PatchManager.Transpile
var context = new MethodContext(baseMethod); var context = new MethodContext(baseMethod);
context.Read(); context.Read();
context.CheckIntegrity(); context.CheckIntegrity();
_log.Trace("Input Method:"); // _log.Trace("Input Method:");
_log.Trace(context.ToHumanMsil); // _log.Trace(context.ToHumanMsil);
var methodContent = (IEnumerable<MsilInstruction>)context.Instructions; var methodContent = (IEnumerable<MsilInstruction>)context.Instructions;
foreach (var transpiler in transpilers) foreach (var transpiler in transpilers)