using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using ILUtils.HarmonyXtensions;
using Microsoft.CodeAnalysis;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("DBJ")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("BepInEx Transpiler Tools")]
[assembly: AssemblyFileVersion("1.0.5.0")]
[assembly: AssemblyInformationalVersion("1.0.5+b9c52bafc41047e18d94bbefe22084e94b3c02dd")]
[assembly: AssemblyProduct("ILUtils")]
[assembly: AssemblyTitle("com.github.decibillyjoel.ILUtils")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/DecibillyJoel/ILUtils")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.5.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
internal static class LCMProjectInfo
{
public const string PROJECT_GUID = "com.github.decibillyjoel.ILUtils";
public const string PROJECT_NAME = "ILUtils";
public const string PROJECT_VERSION = "1.0.5";
}
namespace ILUtils2.Plugin
{
[BepInPlugin("com.github.decibillyjoel.ILUtils", "ILUtils", "1.0.5")]
public class Plugin : BaseUnityPlugin
{
public static readonly string PLUGIN_GUID = "com.github.decibillyjoel.ILUtils";
public static readonly string PLUGIN_NAME = "ILUtils";
public static readonly string PLUGIN_VERSION = "1.0.5";
public static Plugin Instance { get; private set; } = null;
public static void Log(LogLevel level, object data)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
((BaseUnityPlugin)Instance).Logger.Log(level, data);
}
public static void LogFatal(object data)
{
((BaseUnityPlugin)Instance).Logger.LogFatal(data);
}
public static void LogError(object data)
{
((BaseUnityPlugin)Instance).Logger.LogError(data);
}
public static void LogWarning(object data)
{
((BaseUnityPlugin)Instance).Logger.LogWarning(data);
}
public static void LogMessage(object data)
{
((BaseUnityPlugin)Instance).Logger.LogMessage(data);
}
public static void LogInfo(object data)
{
((BaseUnityPlugin)Instance).Logger.LogInfo(data);
}
public static void LogDebug(object data)
{
((BaseUnityPlugin)Instance).Logger.LogDebug(data);
}
private void Awake()
{
Instance = this;
LogInfo("Plugin " + PLUGIN_NAME + " is loaded!");
}
}
}
namespace ILUtils
{
public static class ILPatterns
{
public static int? StackSizeDelta(StackBehaviour stackBehaviour)
{
switch (stackBehaviour)
{
case StackBehaviour.Pop0:
return 0;
case StackBehaviour.Pop1:
return -1;
case StackBehaviour.Pop1_pop1:
return -2;
case StackBehaviour.Popi:
return -1;
case StackBehaviour.Popi_pop1:
return -2;
case StackBehaviour.Popi_popi:
return -2;
case StackBehaviour.Popi_popi8:
return -2;
case StackBehaviour.Popi_popi_popi:
return -3;
case StackBehaviour.Popi_popr4:
return -2;
case StackBehaviour.Popi_popr8:
return -2;
case StackBehaviour.Popref:
return -1;
case StackBehaviour.Popref_pop1:
return -2;
case StackBehaviour.Popref_popi:
return -2;
case StackBehaviour.Popref_popi_popi:
return -3;
case StackBehaviour.Popref_popi_popi8:
return -3;
case StackBehaviour.Popref_popi_popr4:
return -3;
case StackBehaviour.Popref_popi_popr8:
return -3;
case StackBehaviour.Popref_popi_popref:
return -3;
case StackBehaviour.Push0:
return 0;
case StackBehaviour.Push1:
return 1;
case StackBehaviour.Push1_push1:
return 2;
case StackBehaviour.Pushi:
return 1;
case StackBehaviour.Pushi8:
return 1;
case StackBehaviour.Pushr4:
return 1;
case StackBehaviour.Pushr8:
return 1;
case StackBehaviour.Pushref:
return 1;
case StackBehaviour.Popref_popi_pop1:
return -3;
case StackBehaviour.Varpop:
case StackBehaviour.Varpush:
return null;
default:
throw new ArgumentOutOfRangeException(string.Format("[{0}.{1}.{2}] [{3}] is an invalid value", "ILUtils", "ILPatterns", "StackSizeDelta", stackBehaviour));
}
}
public static int? StackSizeDelta(OpCode opCode, object operand)
{
if (opCode == OpCodes.Calli)
{
return null;
}
if (opCode.FlowControl == FlowControl.Call)
{
MethodInfo methodInfo = operand as MethodInfo;
if (methodInfo == null)
{
return null;
}
int num = -methodInfo.GetParameters().Count();
if (opCode != OpCodes.Newobj && methodInfo.CallingConvention.HasFlag(CallingConventions.HasThis) && !methodInfo.CallingConvention.HasFlag(CallingConventions.ExplicitThis))
{
num--;
}
if (opCode == OpCodes.Newobj || methodInfo.ReturnType != typeof(void))
{
num++;
}
return num;
}
int? num2 = StackSizeDelta(opCode.StackBehaviourPush);
int? num3 = StackSizeDelta(opCode.StackBehaviourPop);
if (!num2.HasValue || !num3.HasValue)
{
return null;
}
return num2 + num3;
}
public static int? StackSizeDelta(CodeInstruction code)
{
return StackSizeDelta(code.opcode, code.operand);
}
public static bool EmptiesStack(OpCode opcode)
{
FlowControl flowControl = opcode.FlowControl;
if (flowControl == FlowControl.Branch || (uint)(flowControl - 7) <= 1u)
{
return true;
}
return false;
}
public static bool EmptiesStack(CodeInstruction code)
{
return EmptiesStack(code.opcode);
}
public static Func<CodeInstruction, int, bool> NextEmptyStack(int startSize = 0)
{
return delegate(CodeInstruction code, int index)
{
if (EmptiesStack(code))
{
return true;
}
int num = StackSizeDelta(code) ?? throw new ArgumentException(string.Format("[{0}.{1}.{2}] Encountered uncountable instruction [{3}] {4}", "ILUtils", "ILPatterns", "NextEmptyStack", index, code));
return (startSize += num) == 0;
};
}
}
public class ILStepper
{
public readonly List<CodeInstruction> Instructions;
public int CurrentIndex;
public readonly ILGenerator Generator;
public readonly Dictionary<int, LocalVariableInfo> Locals;
public readonly Dictionary<int, Label> Labels;
public CodeInstruction CurrentInstruction => Instructions[CurrentIndex];
public OpCode CurrentOpCode => CurrentInstruction.opcode;
public object? CurrentOperand => CurrentInstruction.operand;
public ILStepper(IEnumerable<CodeInstruction> codes, ILGenerator generator, MethodBase original, int index = 0)
{
Instructions = codes.ToList();
CurrentIndex = index;
Generator = generator;
Locals = (from code in Instructions
select code.operand as LocalVariableInfo into local
where local != null
select local).Distinct().ToDictionary((LocalVariableInfo local) => local.LocalIndex, (LocalVariableInfo local) => local);
Labels = Instructions.SelectMany((CodeInstruction code) => code.labels).Distinct().ToDictionary((Label label) => label.GetHashCode(), (Label label) => label);
CollectionExtensions.DoIf<LocalVariableInfo>((IEnumerable<LocalVariableInfo>)original.GetMethodBody().LocalVariables, (Func<LocalVariableInfo, bool>)((LocalVariableInfo local) => !Locals.ContainsKey(local.LocalIndex)), (Action<LocalVariableInfo>)delegate(LocalVariableInfo local)
{
Locals.Add(local.LocalIndex, local);
});
Instructions.ForEach(delegate(CodeInstruction code)
{
TrySetLocal(code, code);
});
}
public Label DeclareLabel()
{
Label label = Generator.DefineLabel();
Labels.Add(label.GetHashCode(), label);
return label;
}
public LocalVariableInfo DeclareLocal(Type type, bool pinned = false)
{
LocalVariableInfo localVariableInfo = Generator.DeclareLocal(type, pinned);
Locals.Add(localVariableInfo.LocalIndex, localVariableInfo);
return localVariableInfo;
}
public LocalVariableInfo? TryGetLocal(int localIndex)
{
if (!Locals.TryGetValue(localIndex, out LocalVariableInfo value))
{
return null;
}
return value;
}
public LocalVariableInfo? TryGetLocal(CodeInstruction codeWithLocal)
{
if (!CodeInstructionExtensions.IsLdloc(codeWithLocal, (LocalBuilder)null) && !CodeInstructionExtensions.IsStloc(codeWithLocal, (LocalBuilder)null))
{
return null;
}
return TryGetLocal(codeWithLocal.LocalIndex());
}
public LocalVariableInfo GetLocal(int localIndex, string errorMessage = "No such local variable!")
{
return TryGetLocal(localIndex) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}] | {4}", "ILUtils", "ILStepper", "GetLocal", localIndex, errorMessage));
}
public LocalVariableInfo GetLocal(CodeInstruction codeWithLocal, string errorMessage = "No such local variable!")
{
return TryGetLocal(codeWithLocal) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}] | {4}", "ILUtils", "ILStepper", "GetLocal", codeWithLocal, errorMessage));
}
public LocalVariableInfo? TrySetLocal(CodeInstruction code, LocalVariableInfo local)
{
CodeInstruction val;
if (CodeInstructionExtensions.IsLdloc(code, (LocalBuilder)null))
{
val = CodeInstructionPolyfills.LoadLocal(local, code.opcode == OpCodes.Ldloca || code.opcode == OpCodes.Ldloca_S);
}
else
{
if (!CodeInstructionExtensions.IsStloc(code, (LocalBuilder)null))
{
return null;
}
val = CodeInstructionPolyfills.StoreLocal(local);
}
code.opcode = val.opcode;
code.operand = val.operand;
return local;
}
public LocalVariableInfo? TrySetLocal(CodeInstruction code, int localIndex)
{
LocalVariableInfo localVariableInfo = TryGetLocal(localIndex);
if (localVariableInfo == null)
{
return null;
}
return TrySetLocal(code, localVariableInfo);
}
public LocalVariableInfo? TrySetLocal(CodeInstruction code, CodeInstruction codeWithLocal)
{
LocalVariableInfo localVariableInfo = TryGetLocal(codeWithLocal);
if (localVariableInfo == null)
{
return null;
}
return TrySetLocal(code, localVariableInfo);
}
public LocalVariableInfo SetLocal(CodeInstruction code, LocalVariableInfo local, string errorMessage = "Could not set local!")
{
return TrySetLocal(code, local) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {4}] | {5}", "ILUtils", "ILStepper", "SetLocal", code, local, errorMessage));
}
public LocalVariableInfo SetLocal(CodeInstruction code, int localIndex, string errorMessage = "Could not set local!")
{
return TrySetLocal(code, localIndex) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {4}] | {5}", "ILUtils", "ILStepper", "SetLocal", code, localIndex, errorMessage));
}
public LocalVariableInfo SetLocal(CodeInstruction code, CodeInstruction codeWithLocal, string errorMessage = "Could not set local!")
{
return TrySetLocal(code, codeWithLocal) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {4}] | {5}", "ILUtils", "ILStepper", "SetLocal", code, codeWithLocal, errorMessage));
}
public int? TryFindIL(Func<CodeInstruction, int, bool> searchCondition, int? index = null, int offset = 0, bool reverse = false)
{
index = (index ?? CurrentIndex) + offset + (reverse ? (-1) : 0);
while (index >= 0 && index < Instructions.Count)
{
if (searchCondition(Instructions[index.Value], index.Value))
{
return index;
}
index += ((!reverse) ? 1 : (-1));
}
return null;
}
public int? TryFindIL(Func<CodeInstruction, bool> searchCondition, int? index = null, int offset = 0, bool reverse = false)
{
Func<CodeInstruction, bool> searchCondition2 = searchCondition;
return TryFindIL((CodeInstruction code, int index) => searchCondition2(code), index, offset, reverse);
}
public int FindIL(Func<CodeInstruction, int, bool> searchCondition, int? index = null, int offset = 0, bool reverse = false, string errorMessage = "Not found!")
{
int valueOrDefault = index.GetValueOrDefault();
if (!index.HasValue)
{
valueOrDefault = CurrentIndex;
index = valueOrDefault;
}
return TryFindIL(searchCondition, index, offset, reverse) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {4}, {5} ({6})] | {7}", "ILUtils", "ILStepper", "FindIL", searchCondition, index, reverse, reverse ? "reverse" : "forward", errorMessage));
}
public int FindIL(Func<CodeInstruction, bool> searchCondition, int? index = null, int offset = 0, bool reverse = false, string errorMessage = "Not found!")
{
int valueOrDefault = index.GetValueOrDefault();
if (!index.HasValue)
{
valueOrDefault = CurrentIndex;
index = valueOrDefault;
}
return TryFindIL(searchCondition, index, offset, reverse) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {4}, {5} ({6})] | {7}", "ILUtils", "ILStepper", "FindIL", searchCondition, index, reverse, reverse ? "reverse" : "forward", errorMessage));
}
public int? TryGotoIL(Func<CodeInstruction, bool> searchCondition, int? index = null, int offset = 0, bool reverse = false)
{
index = TryFindIL(searchCondition, index, offset, reverse);
CurrentIndex = index ?? CurrentIndex;
return index;
}
public int? TryGotoIL(Func<CodeInstruction, int, bool> searchCondition, int? index = null, int offset = 0, bool reverse = false)
{
index = TryFindIL(searchCondition, index, offset, reverse);
CurrentIndex = index ?? CurrentIndex;
return index;
}
public int GotoIL(Func<CodeInstruction, bool> searchCondition, int? index = null, int offset = 0, bool reverse = false, string errorMessage = "Not found!")
{
int valueOrDefault = index.GetValueOrDefault();
if (!index.HasValue)
{
valueOrDefault = CurrentIndex;
index = valueOrDefault;
}
return CurrentIndex = TryFindIL(searchCondition, index, offset, reverse) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {4}, {5} ({6})] | {7}", "ILUtils", "ILStepper", "GotoIL", searchCondition, index, reverse, reverse ? "reverse" : "forward", errorMessage));
}
public int GotoIL(Func<CodeInstruction, int, bool> searchCondition, int? index = null, int offset = 0, bool reverse = false, string errorMessage = "Not found!")
{
int valueOrDefault = index.GetValueOrDefault();
if (!index.HasValue)
{
valueOrDefault = CurrentIndex;
index = valueOrDefault;
}
return CurrentIndex = TryFindIL(searchCondition, index, offset, reverse) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {4}, {5} ({6})] | {7}", "ILUtils", "ILStepper", "GotoIL", searchCondition, index, reverse, reverse ? "reverse" : "forward", errorMessage));
}
public int? TryFindIndex(int? index = null, int offset = 0, int leftBoundOffset = 0, int rightBoundOffset = 1)
{
index = (index ?? CurrentIndex) + offset;
if (index < leftBoundOffset || index > Instructions.Count - 1 + rightBoundOffset)
{
return null;
}
return index;
}
public int FindIndex(int? index = null, int offset = 0, int leftBoundOffset = 0, int rightBoundOffset = 1, string errorMessage = "Out of bounds!")
{
int valueOrDefault = index.GetValueOrDefault();
if (!index.HasValue)
{
valueOrDefault = CurrentIndex;
index = valueOrDefault;
}
return TryFindIndex(index, offset, leftBoundOffset, rightBoundOffset) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3} ({4} + {5}), {6} (0 + {7}), {8} ({9} + {10})] | {11}", "ILUtils", "ILStepper", "FindIndex", index + offset, index, offset, leftBoundOffset, leftBoundOffset, Instructions.Count - 1 + rightBoundOffset, Instructions.Count - 1, rightBoundOffset, errorMessage));
}
public int? TryGotoIndex(int? index = null, int offset = 0, int leftBoundOffset = 0, int rightBoundOffset = 1)
{
index = TryFindIndex(index, offset, leftBoundOffset, rightBoundOffset);
CurrentIndex = index ?? CurrentIndex;
return index;
}
public int GotoIndex(int? index = null, int offset = 0, int leftBoundOffset = 0, int rightBoundOffset = 1, string errorMessage = "Out of bounds!")
{
int valueOrDefault = index.GetValueOrDefault();
if (!index.HasValue)
{
valueOrDefault = CurrentIndex;
index = valueOrDefault;
}
return CurrentIndex = TryFindIndex(index, offset, leftBoundOffset, rightBoundOffset) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3} ({4} + {5}), {6} (0 + {7}), {8} ({9} + {10})] | {11}", "ILUtils", "ILStepper", "GotoIndex", index + offset, index, offset, leftBoundOffset, leftBoundOffset, Instructions.Count - 1 + rightBoundOffset, Instructions.Count - 1, rightBoundOffset, errorMessage));
}
public List<CodeInstruction>? TryInsertIL(List<CodeInstruction> codeRange, int? index = null, bool shiftCurrentIndex = true, bool pinLabels = true, bool pinBlocks = true)
{
index = TryFindIndex(index);
if (!index.HasValue)
{
return null;
}
codeRange = ((IEnumerable<CodeInstruction>)codeRange).Select((Func<CodeInstruction, CodeInstruction>)((CodeInstruction code) => new CodeInstruction(code))).ToList();
if (index < Instructions.Count && codeRange.Count > 0)
{
if (pinLabels)
{
CodeInstructionExtensions.MoveLabelsTo(Instructions[index.Value], codeRange[0]);
}
if (pinBlocks)
{
CodeInstructionExtensions.MoveBlocksTo(Instructions[index.Value], codeRange[0]);
}
}
Instructions.InsertRange(index.Value, codeRange);
if (shiftCurrentIndex && CurrentIndex >= index)
{
CurrentIndex += codeRange.Count;
}
return codeRange;
}
public List<CodeInstruction>? TryInsertIL(CodeInstruction? code, int? index = null, bool shiftCurrentIndex = true, bool pinLabels = true, bool pinBlocks = true)
{
return TryInsertIL((code != null) ? new List<CodeInstruction>(1) { code } : new List<CodeInstruction>(), index, shiftCurrentIndex, pinLabels, pinBlocks);
}
public List<CodeInstruction> InsertIL(List<CodeInstruction> codeRange, int? index = null, bool shiftCurrentIndex = true, bool pinLabels = true, bool pinBlocks = true, string errorMessage = "Out of bounds!")
{
int valueOrDefault = index.GetValueOrDefault();
if (!index.HasValue)
{
valueOrDefault = CurrentIndex;
index = valueOrDefault;
}
return TryInsertIL(codeRange, index, shiftCurrentIndex, pinLabels, pinBlocks) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {4}, {5} ({6})] | {7}", "ILUtils", "ILStepper", "InsertIL", codeRange, index, shiftCurrentIndex, shiftCurrentIndex ? "shift current index" : "dont shift current index", errorMessage));
}
public List<CodeInstruction> InsertIL(CodeInstruction? code, int? index = null, bool shiftCurrentIndex = true, bool pinLabels = true, bool pinBlocks = true, string errorMessage = "Out of bounds!")
{
int valueOrDefault = index.GetValueOrDefault();
if (!index.HasValue)
{
valueOrDefault = CurrentIndex;
index = valueOrDefault;
}
return TryInsertIL((code != null) ? new List<CodeInstruction>(1) { code } : new List<CodeInstruction>(), index, shiftCurrentIndex, pinLabels, pinBlocks) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {4}, {5} ({6})] | {7}", "ILUtils", "ILStepper", "InsertIL", code, index, shiftCurrentIndex, shiftCurrentIndex ? "shift current index" : "dont shift current index", errorMessage));
}
public List<CodeInstruction>? TryRemoveIL(int? startIndex = null, int? endIndex = null, bool shiftCurrentIndex = true, bool pinLabels = true, bool pinBlocks = true)
{
startIndex = TryFindIndex(startIndex);
endIndex = TryFindIndex(endIndex);
if (!startIndex.HasValue || !endIndex.HasValue)
{
return null;
}
if (startIndex > endIndex)
{
int? num = endIndex;
endIndex = startIndex;
startIndex = num;
}
if (endIndex >= Instructions.Count)
{
return null;
}
int num2 = endIndex.Value - startIndex.Value;
List<CodeInstruction> range = Instructions.GetRange(startIndex.Value, num2);
Instructions.RemoveRange(startIndex.Value, num2);
if (startIndex < Instructions.Count)
{
range.ForEach(delegate(CodeInstruction code)
{
if (pinLabels)
{
CodeInstructionExtensions.MoveLabelsFrom(Instructions[startIndex.Value], code);
}
if (pinBlocks)
{
CodeInstructionExtensions.MoveBlocksFrom(Instructions[startIndex.Value], code);
}
});
}
if (shiftCurrentIndex && CurrentIndex > startIndex)
{
CurrentIndex = Math.Max(startIndex.Value, CurrentIndex - num2);
}
return range;
}
public List<CodeInstruction> RemoveIL(int? startIndex = null, int? endIndex = null, bool shiftCurrentIndex = true, bool pinLabels = true, bool pinBlocks = true, string errorMessage = "Out of bounds!")
{
int valueOrDefault = startIndex.GetValueOrDefault();
if (!startIndex.HasValue)
{
valueOrDefault = CurrentIndex;
startIndex = valueOrDefault;
}
valueOrDefault = endIndex.GetValueOrDefault();
if (!endIndex.HasValue)
{
valueOrDefault = CurrentIndex;
endIndex = valueOrDefault;
}
return TryRemoveIL(startIndex, endIndex, shiftCurrentIndex, pinLabels, pinBlocks) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {4}, {5} ({6})] | {7}", "ILUtils", "ILStepper", "RemoveIL", startIndex, endIndex, shiftCurrentIndex, shiftCurrentIndex ? "shift current index" : "dont shift current index", errorMessage));
}
public List<CodeInstruction>? TryGetIL(int? startIndex = null, int? endIndex = null)
{
startIndex = TryFindIndex(startIndex);
endIndex = TryFindIndex(endIndex);
if (!startIndex.HasValue || !endIndex.HasValue)
{
return null;
}
if (startIndex > endIndex)
{
int? num = endIndex;
endIndex = startIndex;
startIndex = num;
}
if (endIndex >= Instructions.Count)
{
return null;
}
int count = endIndex.Value - startIndex.Value;
return Instructions.GetRange(startIndex.Value, count);
}
public List<CodeInstruction> GetIL(int? startIndex = null, int? endIndex = null, string errorMessage = "Out of bounds!")
{
int valueOrDefault = startIndex.GetValueOrDefault();
if (!startIndex.HasValue)
{
valueOrDefault = CurrentIndex;
startIndex = valueOrDefault;
}
valueOrDefault = endIndex.GetValueOrDefault();
if (!endIndex.HasValue)
{
valueOrDefault = CurrentIndex;
endIndex = valueOrDefault;
}
return TryGetIL(startIndex, endIndex) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {4}] | {5}", "ILUtils", "ILStepper", "GetIL", startIndex, endIndex, errorMessage));
}
public List<Label>? TryMoveAllLabels(List<CodeInstruction> sourceCodeRange, List<CodeInstruction> destinationCodeRange)
{
List<CodeInstruction> destinationCodeRange2 = destinationCodeRange;
if (sourceCodeRange.Count != destinationCodeRange2.Count)
{
return null;
}
return sourceCodeRange.SelectMany(delegate(CodeInstruction sourceCode, int sourceCodeIndex)
{
List<Label> list = CodeInstructionExtensions.ExtractLabels(sourceCode);
destinationCodeRange2[sourceCodeIndex].labels.AddRange(list);
return list;
}).ToList();
}
public List<Label>? TryMoveAllLabels(List<CodeInstruction> sourceCodeRange, CodeInstruction destinationCode)
{
return TryMoveAllLabels(sourceCodeRange, Enumerable.Repeat<CodeInstruction>(destinationCode, sourceCodeRange.Count).ToList());
}
public List<Label> MoveAllLabels(List<CodeInstruction> sourceCodeRange, List<CodeInstruction> destinationCodeRange, string errorMessage = "Source and destination instruction count don't match!")
{
return TryMoveAllLabels(sourceCodeRange, destinationCodeRange) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {4}] | {5}", "ILUtils", "ILStepper", "MoveAllLabels", sourceCodeRange, destinationCodeRange, errorMessage));
}
public List<Label> MoveAllLabels(List<CodeInstruction> sourceCodeRange, CodeInstruction destinationCode, string errorMessage = "Source and destination instruction count don't match!")
{
return TryMoveAllLabels(sourceCodeRange, Enumerable.Repeat<CodeInstruction>(destinationCode, sourceCodeRange.Count).ToList()) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {{{4}, ...}}] | {5}", "ILUtils", "ILStepper", "MoveAllLabels", sourceCodeRange, destinationCode, errorMessage));
}
public List<Label>? TryShiftAllLabels(int? startIndex = null, int? endIndex = null, int shiftBy = 1)
{
List<CodeInstruction> list = TryGetIL(startIndex, endIndex);
if (list == null)
{
return null;
}
int? startIndex2 = TryFindIndex(startIndex, shiftBy);
int? endIndex2 = TryFindIndex(endIndex, shiftBy);
if (!startIndex2.HasValue || !endIndex2.HasValue)
{
return null;
}
List<CodeInstruction> list2 = TryGetIL(startIndex2, endIndex2);
if (list2 == null)
{
return null;
}
return TryMoveAllLabels(list, list2);
}
public List<Label> ShiftAllLabels(int? startIndex = null, int? endIndex = null, int shiftBy = 1, string errorMessage = "Source and/or destination instructions out of bounds!")
{
int valueOrDefault = startIndex.GetValueOrDefault();
if (!startIndex.HasValue)
{
valueOrDefault = CurrentIndex;
startIndex = valueOrDefault;
}
valueOrDefault = endIndex.GetValueOrDefault();
if (!endIndex.HasValue)
{
valueOrDefault = CurrentIndex;
endIndex = valueOrDefault;
}
return TryShiftAllLabels(startIndex, endIndex) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {4}, {5} ({6} + {7}), {8} ({9} + {10})] | {11}", "ILUtils", "ILStepper", "ShiftAllLabels", startIndex, endIndex, startIndex + shiftBy, startIndex, shiftBy, endIndex + shiftBy, endIndex, shiftBy, errorMessage));
}
public List<ExceptionBlock>? TryMoveAllBlocks(List<CodeInstruction> sourceCodeRange, List<CodeInstruction> destinationCodeRange)
{
List<CodeInstruction> destinationCodeRange2 = destinationCodeRange;
if (sourceCodeRange.Count != destinationCodeRange2.Count)
{
return null;
}
return sourceCodeRange.SelectMany(delegate(CodeInstruction sourceCode, int sourceCodeIndex)
{
List<ExceptionBlock> list = CodeInstructionExtensions.ExtractBlocks(sourceCode);
destinationCodeRange2[sourceCodeIndex].blocks.AddRange(list);
return list;
}).ToList();
}
public List<ExceptionBlock>? TryMoveAllBlocks(List<CodeInstruction> sourceCodeRange, CodeInstruction destinationCode)
{
return TryMoveAllBlocks(sourceCodeRange, Enumerable.Repeat<CodeInstruction>(destinationCode, sourceCodeRange.Count).ToList());
}
public List<ExceptionBlock> MoveAllBlocks(List<CodeInstruction> sourceCodeRange, List<CodeInstruction> destinationCodeRange, string errorMessage = "Source and destination instruction count don't match!")
{
return TryMoveAllBlocks(sourceCodeRange, destinationCodeRange) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {4}] | {5}", "ILUtils", "ILStepper", "MoveAllBlocks", sourceCodeRange, destinationCodeRange, errorMessage));
}
public List<ExceptionBlock> MoveAllBlocks(List<CodeInstruction> sourceCodeRange, CodeInstruction destinationCode, string errorMessage = "Source and destination instruction count don't match!")
{
return TryMoveAllBlocks(sourceCodeRange, Enumerable.Repeat<CodeInstruction>(destinationCode, sourceCodeRange.Count).ToList()) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {{{4}, ...}}] | {5}", "ILUtils", "ILStepper", "MoveAllBlocks", sourceCodeRange, destinationCode, errorMessage));
}
public List<ExceptionBlock>? TryShiftAllBlocks(int? startIndex = null, int? endIndex = null, int shiftBy = 1)
{
List<CodeInstruction> list = TryGetIL(startIndex, endIndex);
if (list == null)
{
return null;
}
int? startIndex2 = TryFindIndex(startIndex, shiftBy);
int? endIndex2 = TryFindIndex(endIndex, shiftBy);
if (!startIndex2.HasValue || !endIndex2.HasValue)
{
return null;
}
List<CodeInstruction> list2 = TryGetIL(startIndex2, endIndex2);
if (list2 == null)
{
return null;
}
return TryMoveAllBlocks(list, list2);
}
public List<ExceptionBlock> ShiftAllBlocks(int? startIndex = null, int? endIndex = null, int shiftBy = 1, string errorMessage = "Source and/or destination instructions out of bounds!")
{
int valueOrDefault = startIndex.GetValueOrDefault();
if (!startIndex.HasValue)
{
valueOrDefault = CurrentIndex;
startIndex = valueOrDefault;
}
valueOrDefault = endIndex.GetValueOrDefault();
if (!endIndex.HasValue)
{
valueOrDefault = CurrentIndex;
endIndex = valueOrDefault;
}
return TryShiftAllBlocks(startIndex, endIndex) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {4}, {5} ({6} + {7}), {8} ({9} + {10})] | {11}", "ILUtils", "ILStepper", "ShiftAllBlocks", startIndex, endIndex, startIndex + shiftBy, startIndex, shiftBy, endIndex + shiftBy, endIndex, shiftBy, errorMessage));
}
public List<Label> ExtractAllLabels(List<CodeInstruction> codeRange)
{
return codeRange.SelectMany((CodeInstruction code) => CodeInstructionExtensions.ExtractLabels(code)).ToList();
}
public List<Label>? TryExtractAllLabels(int? startIndex = null, int? endIndex = null)
{
List<CodeInstruction> list = TryGetIL(startIndex, endIndex);
if (list == null)
{
return null;
}
return ExtractAllLabels(list);
}
public List<Label> ExtractAllLabels(int? startIndex = null, int? endIndex = null, string errorMessage = "Out of bounds!")
{
int valueOrDefault = startIndex.GetValueOrDefault();
if (!startIndex.HasValue)
{
valueOrDefault = CurrentIndex;
startIndex = valueOrDefault;
}
return TryExtractAllLabels(startIndex, endIndex) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {4}] | {5}", "ILUtils", "ILStepper", "ExtractAllLabels", startIndex, endIndex, errorMessage));
}
public List<Label> ExtractAllBlocks(List<CodeInstruction> codeRange)
{
return codeRange.SelectMany((CodeInstruction code) => CodeInstructionExtensions.ExtractLabels(code)).ToList();
}
public List<Label>? TryExtractAllBlocks(int? startIndex = null, int? endIndex = null)
{
List<CodeInstruction> list = TryGetIL(startIndex, endIndex);
if (list == null)
{
return null;
}
return ExtractAllBlocks(list);
}
public List<Label> ExtractAllBlocks(int? startIndex = null, int? endIndex = null, string errorMessage = "Out of bounds!")
{
int valueOrDefault = startIndex.GetValueOrDefault();
if (!startIndex.HasValue)
{
valueOrDefault = CurrentIndex;
startIndex = valueOrDefault;
}
valueOrDefault = endIndex.GetValueOrDefault();
if (!endIndex.HasValue)
{
valueOrDefault = CurrentIndex;
endIndex = valueOrDefault;
}
return TryExtractAllBlocks(startIndex, endIndex) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {4}] | {5}", "ILUtils", "ILStepper", "ExtractAllBlocks", startIndex, endIndex, errorMessage));
}
public List<CodeInstruction>? TryShiftIL(int? startIndex = null, int? endIndex = null, int shiftBy = 1, bool shiftCurrentIndex = true)
{
startIndex = TryFindIndex(startIndex);
endIndex = TryFindIndex(endIndex);
if (!startIndex.HasValue || !endIndex.HasValue)
{
return null;
}
if (startIndex > endIndex)
{
int? num = endIndex;
endIndex = startIndex;
startIndex = num;
}
if (endIndex >= Instructions.Count)
{
return null;
}
int num2 = endIndex.Value - startIndex.Value;
int? index = TryFindIndex(startIndex, shiftBy, 0, -num2 + 1);
if (!index.HasValue)
{
return null;
}
if (shiftCurrentIndex && CurrentIndex >= startIndex && CurrentIndex < endIndex)
{
CurrentIndex += shiftBy;
shiftCurrentIndex = false;
}
string errorMessage = string.Format("[{0}.{1}.{2}] [{3}, {4}, {5} ({6} + {7}), {8} ({9} + {10})] Somehow calculated invalid parameters. This should never happen!", "ILUtils", "ILStepper", "TryShiftIL", startIndex, endIndex, startIndex + shiftBy, startIndex, shiftBy, endIndex + shiftBy, endIndex, shiftBy);
List<CodeInstruction> codeRange = RemoveIL(startIndex, endIndex, shiftCurrentIndex, pinLabels: false, pinBlocks: false, errorMessage);
return InsertIL(codeRange, index, shiftCurrentIndex, pinLabels: false, pinBlocks: false, errorMessage);
}
public List<CodeInstruction> ShiftIL(int? startIndex = null, int? endIndex = null, int shiftBy = 1, bool shiftCurrentIndex = true, string errorMessage = "Source and/or destination instructions out of bounds!")
{
int valueOrDefault = startIndex.GetValueOrDefault();
if (!startIndex.HasValue)
{
valueOrDefault = CurrentIndex;
startIndex = valueOrDefault;
}
valueOrDefault = endIndex.GetValueOrDefault();
if (!endIndex.HasValue)
{
valueOrDefault = CurrentIndex;
endIndex = valueOrDefault;
}
return TryShiftIL(startIndex, endIndex, shiftBy, shiftCurrentIndex) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {4}, {5} ({6} + {7}), {8} ({9} + {10})] | {11}", "ILUtils", "ILStepper", "ShiftIL", startIndex, endIndex, startIndex + shiftBy, startIndex, shiftBy, endIndex + shiftBy, endIndex, shiftBy, errorMessage));
}
public List<CodeInstruction>? TryOverwriteIL(List<CodeInstruction> codeRange, int? index = null, bool pinLabels = true, bool pinBlocks = true)
{
int valueOrDefault = index.GetValueOrDefault();
if (!index.HasValue)
{
valueOrDefault = CurrentIndex;
index = valueOrDefault;
}
List<CodeInstruction> removedIL = TryRemoveIL(index, index + codeRange.Count(), shiftCurrentIndex: false, pinLabels: false, pinBlocks: false);
if (removedIL == null)
{
return null;
}
codeRange = codeRange.Select(delegate(CodeInstruction code, int i)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Expected O, but got Unknown
code = new CodeInstruction(code);
if (pinLabels)
{
CodeInstructionExtensions.MoveLabelsTo(removedIL[i], code);
}
if (pinBlocks)
{
CodeInstructionExtensions.MoveBlocksTo(removedIL[i], code);
}
return code;
}).ToList();
return TryInsertIL(codeRange, index, shiftCurrentIndex: false, pinLabels: false, pinBlocks: false);
}
public List<CodeInstruction>? TryOverwriteIL(CodeInstruction? code, int? index = null, bool pinLabels = true, bool pinBlocks = true)
{
return TryOverwriteIL((code != null) ? new List<CodeInstruction>(1) { code } : new List<CodeInstruction>(), index, pinLabels, pinBlocks);
}
public List<CodeInstruction> OverwriteIL(List<CodeInstruction> codeRange, int? index = null, bool pinLabels = true, bool pinBlocks = true, string errorMessage = "Out of bounds!")
{
int valueOrDefault = index.GetValueOrDefault();
if (!index.HasValue)
{
valueOrDefault = CurrentIndex;
index = valueOrDefault;
}
return TryOverwriteIL(codeRange, index, pinLabels, pinBlocks) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {4}, {5} ({6} + {7})] | {8}", "ILUtils", "ILStepper", "OverwriteIL", codeRange, index, index + codeRange.Count(), index, codeRange.Count(), errorMessage));
}
public List<CodeInstruction> OverwriteIL(CodeInstruction? code, int? index = null, bool pinLabels = true, bool pinBlocks = true, string errorMessage = "Out of bounds!")
{
int valueOrDefault = index.GetValueOrDefault();
if (!index.HasValue)
{
valueOrDefault = CurrentIndex;
index = valueOrDefault;
}
return TryOverwriteIL((code != null) ? new List<CodeInstruction>(1) { code } : new List<CodeInstruction>(), index, pinLabels, pinBlocks) ?? throw new Exception(string.Format("[{0}.{1}.{2}] [{3}, {4}, {5} ({6} + {7})] | {8}", "ILUtils", "ILStepper", "OverwriteIL", code, index, index + ((code != null) ? 1 : 0), index, (code != null) ? 1 : 0, errorMessage));
}
}
}
namespace ILUtils.HarmonyXtensions
{
public static class CodeInstructionPolyfills
{
public static readonly OpCode[] ARGUMENTED_LOCAL_INSTRUCTS = new OpCode[6]
{
OpCodes.Ldloc,
OpCodes.Stloc,
OpCodes.Ldloca,
OpCodes.Ldloc_S,
OpCodes.Stloc_S,
OpCodes.Ldloca_S
};
public static readonly OpCode[] LOAD_FIELD_INSTRUCTS = new OpCode[4]
{
OpCodes.Ldfld,
OpCodes.Ldsfld,
OpCodes.Ldflda,
OpCodes.Ldsflda
};
public static readonly OpCode[] STORE_FIELD_INSTRUCTS = new OpCode[2]
{
OpCodes.Stfld,
OpCodes.Stsfld
};
public static bool IsValid(this OpCode code)
{
return code.Size > 0;
}
public static CodeInstruction Call(Type type, string name, Type[]? parameters = null, Type[]? generics = null)
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Expected O, but got Unknown
MethodInfo methodInfo = AccessTools.Method(type, name, parameters, generics) ?? throw new ArgumentException($"No method found for type={type}, name={name}, parameters={GeneralExtensions.Description(parameters)}, generics={GeneralExtensions.Description(generics)}");
return new CodeInstruction(OpCodes.Call, (object)methodInfo);
}
public static bool Calls(this CodeInstruction codeInstruction, Type type, string name, Type[]? parameters = null, Type[]? generics = null)
{
MethodInfo methodInfo = AccessTools.Method(type, name, parameters, generics) ?? throw new ArgumentException($"No method found for type={type}, name={name}, parameters={GeneralExtensions.Description(parameters)}, generics={GeneralExtensions.Description(generics)}");
return CodeInstructionExtensions.Calls(codeInstruction, methodInfo);
}
public static CodeInstruction Call(string typeColonMethodname, Type[]? parameters = null, Type[]? generics = null)
{
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Expected O, but got Unknown
MethodInfo methodInfo = AccessTools.Method(typeColonMethodname, parameters, generics) ?? throw new ArgumentException("No method found for " + typeColonMethodname + ", parameters=" + GeneralExtensions.Description(parameters) + ", generics=" + GeneralExtensions.Description(generics));
return new CodeInstruction(OpCodes.Call, (object)methodInfo);
}
public static bool Calls(this CodeInstruction codeInstruction, string typeColonMethodname, Type[]? parameters = null, Type[]? generics = null)
{
MethodInfo methodInfo = AccessTools.Method(typeColonMethodname, parameters, generics) ?? throw new ArgumentException("No method found for " + typeColonMethodname + ", parameters=" + GeneralExtensions.Description(parameters) + ", generics=" + GeneralExtensions.Description(generics));
return CodeInstructionExtensions.Calls(codeInstruction, methodInfo);
}
public static CodeInstruction Call(Expression<Action> expression)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
return new CodeInstruction(OpCodes.Call, (object)SymbolExtensions.GetMethodInfo(expression));
}
public static CodeInstruction Call<T>(Expression<Action<T>> expression)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
return new CodeInstruction(OpCodes.Call, (object)SymbolExtensions.GetMethodInfo<T>(expression));
}
public static CodeInstruction Call<T, TResult>(Expression<Func<T, TResult>> expression)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
return new CodeInstruction(OpCodes.Call, (object)SymbolExtensions.GetMethodInfo<T, TResult>(expression));
}
public static CodeInstruction Call(LambdaExpression expression)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
return new CodeInstruction(OpCodes.Call, (object)SymbolExtensions.GetMethodInfo(expression));
}
public static CodeInstruction CallClosure<T>(T closure) where T : Delegate
{
return Transpilers.EmitDelegate<T>(closure);
}
public static CodeInstruction CallConstructor(Type type, Type[]? parameters = null, bool searchForStatic = false)
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
ConstructorInfo constructorInfo = AccessTools.Constructor(type, parameters, searchForStatic) ?? throw new ArgumentException($"No constructor found for type={type}, parameters={GeneralExtensions.Description(parameters)}, searchForStatic={searchForStatic}");
return new CodeInstruction(OpCodes.Newobj, (object)constructorInfo);
}
public static CodeInstruction LoadField(Type type, string name, bool useAddress = false)
{
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Expected O, but got Unknown
FieldInfo fieldInfo = AccessTools.Field(type, name) ?? throw new ArgumentException($"No field found for {type} and {name}");
return new CodeInstruction((!useAddress) ? (fieldInfo.IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld) : (fieldInfo.IsStatic ? OpCodes.Ldsflda : OpCodes.Ldflda), (object)fieldInfo);
}
public static CodeInstruction StoreField(Type type, string name)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Expected O, but got Unknown
FieldInfo fieldInfo = AccessTools.Field(type, name) ?? throw new ArgumentException($"No field found for {type} and {name}");
return new CodeInstruction(fieldInfo.IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, (object)fieldInfo);
}
public static bool LoadsField(this CodeInstruction codeInstruction, Type type, string name, bool byAddress = false)
{
FieldInfo fieldInfo = AccessTools.DeclaredField(type, name);
if (fieldInfo != null)
{
return CodeInstructionExtensions.LoadsField(codeInstruction, fieldInfo, byAddress);
}
return false;
}
public static bool StoresField(this CodeInstruction codeInstruction, Type type, string name)
{
FieldInfo fieldInfo = AccessTools.DeclaredField(type, name);
if (fieldInfo != null)
{
return CodeInstructionExtensions.StoresField(codeInstruction, fieldInfo);
}
return false;
}
public static int LocalIndex(this CodeInstruction code)
{
if (code.opcode == OpCodes.Ldloc_0 || code.opcode == OpCodes.Stloc_0)
{
return 0;
}
if (code.opcode == OpCodes.Ldloc_1 || code.opcode == OpCodes.Stloc_1)
{
return 1;
}
if (code.opcode == OpCodes.Ldloc_2 || code.opcode == OpCodes.Stloc_2)
{
return 2;
}
if (code.opcode == OpCodes.Ldloc_3 || code.opcode == OpCodes.Stloc_3)
{
return 3;
}
if (ARGUMENTED_LOCAL_INSTRUCTS.Contains(code.opcode))
{
int? num = (code.operand as LocalVariableInfo)?.LocalIndex;
return Convert.ToInt32(num.HasValue ? ((object)num.GetValueOrDefault()) : code.operand);
}
throw new ArgumentException("Instruction is not a load or store", "code");
}
public static CodeInstruction LoadLocal(int index, bool useAddress = false)
{
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Expected O, but got Unknown
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Expected O, but got Unknown
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Expected O, but got Unknown
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Expected O, but got Unknown
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Expected O, but got Unknown
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Expected O, but got Unknown
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Expected O, but got Unknown
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Expected O, but got Unknown
if (useAddress)
{
if (index < 256)
{
return new CodeInstruction(OpCodes.Ldloca_S, (object)Convert.ToByte(index));
}
return new CodeInstruction(OpCodes.Ldloca, (object)index);
}
if (index < 256)
{
return (CodeInstruction)(index switch
{
0 => (object)new CodeInstruction(OpCodes.Ldloc_0, (object)null),
1 => (object)new CodeInstruction(OpCodes.Ldloc_1, (object)null),
2 => (object)new CodeInstruction(OpCodes.Ldloc_2, (object)null),
3 => (object)new CodeInstruction(OpCodes.Ldloc_3, (object)null),
_ => (object)new CodeInstruction(OpCodes.Ldloc_S, (object)Convert.ToByte(index)),
});
}
return new CodeInstruction(OpCodes.Ldloc, (object)index);
}
public static CodeInstruction LoadLocal(LocalVariableInfo local, bool useAddress = false)
{
return LoadLocal(local.LocalIndex, useAddress);
}
public static CodeInstruction StoreLocal(int index)
{
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Expected O, but got Unknown
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Expected O, but got Unknown
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Expected O, but got Unknown
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Expected O, but got Unknown
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Expected O, but got Unknown
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Expected O, but got Unknown
if (index < 256)
{
return (CodeInstruction)(index switch
{
0 => (object)new CodeInstruction(OpCodes.Stloc_0, (object)null),
1 => (object)new CodeInstruction(OpCodes.Stloc_1, (object)null),
2 => (object)new CodeInstruction(OpCodes.Stloc_2, (object)null),
3 => (object)new CodeInstruction(OpCodes.Stloc_3, (object)null),
_ => (object)new CodeInstruction(OpCodes.Stloc_S, (object)Convert.ToByte(index)),
});
}
return new CodeInstruction(OpCodes.Stloc, (object)index);
}
public static CodeInstruction StoreLocal(LocalVariableInfo local)
{
return StoreLocal(local.LocalIndex);
}
public static bool LoadsLocal(this CodeInstruction code, LocalVariableInfo? local = null)
{
if (CodeInstructionExtensions.IsLdloc(code, (LocalBuilder)null))
{
if (local != null)
{
return code.LocalIndex() == local.LocalIndex;
}
return true;
}
return false;
}
public static bool LoadsLocal(this CodeInstruction code, int index)
{
if (CodeInstructionExtensions.IsLdloc(code, (LocalBuilder)null))
{
return code.LocalIndex() == index;
}
return false;
}
public static bool StoresLocal(this CodeInstruction code, LocalVariableInfo? local = null)
{
if (CodeInstructionExtensions.IsStloc(code, (LocalBuilder)null))
{
if (local != null)
{
return code.LocalIndex() == local.LocalIndex;
}
return true;
}
return false;
}
public static bool StoresLocal(this CodeInstruction code, int index)
{
if (CodeInstructionExtensions.IsStloc(code, (LocalBuilder)null))
{
return code.LocalIndex() == index;
}
return false;
}
public static CodeInstruction LoadArgument(int index, bool useAddress = false)
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Expected O, but got Unknown
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Expected O, but got Unknown
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Expected O, but got Unknown
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Expected O, but got Unknown
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Expected O, but got Unknown
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Expected O, but got Unknown
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Expected O, but got Unknown
if (useAddress)
{
if (index >= 256)
{
return new CodeInstruction(OpCodes.Ldarga, (object)index);
}
return new CodeInstruction(OpCodes.Ldarga_S, (object)Convert.ToByte(index));
}
if (index != 0)
{
if (index != 1)
{
if (index != 2)
{
if (index != 3)
{
if (index >= 256)
{
return new CodeInstruction(OpCodes.Ldarg, (object)index);
}
return new CodeInstruction(OpCodes.Ldarg_S, (object)Convert.ToByte(index));
}
return new CodeInstruction(OpCodes.Ldarg_3, (object)null);
}
return new CodeInstruction(OpCodes.Ldarg_2, (object)null);
}
return new CodeInstruction(OpCodes.Ldarg_1, (object)null);
}
return new CodeInstruction(OpCodes.Ldarg_0, (object)null);
}
public static int ArgumentIndex(this CodeInstruction code)
{
if (code.opcode == OpCodes.Ldarg_0)
{
return 0;
}
if (code.opcode == OpCodes.Ldarg_1)
{
return 1;
}
if (code.opcode == OpCodes.Ldarg_2)
{
return 2;
}
if (code.opcode == OpCodes.Ldarg_3)
{
return 3;
}
if (code.opcode == OpCodes.Ldarg_S || code.opcode == OpCodes.Ldarg)
{
return Convert.ToInt32(code.operand);
}
if (code.opcode == OpCodes.Starg_S || code.opcode == OpCodes.Starg)
{
return Convert.ToInt32(code.operand);
}
if (code.opcode == OpCodes.Ldarga_S || code.opcode == OpCodes.Ldarga)
{
return Convert.ToInt32(code.operand);
}
throw new ArgumentException("Instruction is not a load or store", "code");
}
public static CodeInstruction StoreArgument(int index)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Expected O, but got Unknown
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Expected O, but got Unknown
if (index >= 256)
{
return new CodeInstruction(OpCodes.Starg, (object)index);
}
return new CodeInstruction(OpCodes.Starg_S, (object)Convert.ToByte(index));
}
public static bool LoadsString(this CodeInstruction code, string str)
{
if (code.opcode != OpCodes.Ldstr)
{
return false;
}
string text = Convert.ToString(code.operand);
return text == str;
}
public static CodeInstruction LoadConstant(sbyte number)
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Expected O, but got Unknown
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Expected O, but got Unknown
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Expected O, but got Unknown
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Expected O, but got Unknown
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Expected O, but got Unknown
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Expected O, but got Unknown
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Expected O, but got Unknown
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Expected O, but got Unknown
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Expected O, but got Unknown
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Expected O, but got Unknown
return (CodeInstruction)(number switch
{
-1 => (object)new CodeInstruction(OpCodes.Ldc_I4_M1, (object)null),
0 => (object)new CodeInstruction(OpCodes.Ldc_I4_0, (object)null),
1 => (object)new CodeInstruction(OpCodes.Ldc_I4_1, (object)null),
2 => (object)new CodeInstruction(OpCodes.Ldc_I4_2, (object)null),
3 => (object)new CodeInstruction(OpCodes.Ldc_I4_3, (object)null),
4 => (object)new CodeInstruction(OpCodes.Ldc_I4_4, (object)null),
5 => (object)new CodeInstruction(OpCodes.Ldc_I4_5, (object)null),
6 => (object)new CodeInstruction(OpCodes.Ldc_I4_6, (object)null),
7 => (object)new CodeInstruction(OpCodes.Ldc_I4_7, (object)null),
8 => (object)new CodeInstruction(OpCodes.Ldc_I4_8, (object)null),
_ => (object)new CodeInstruction(OpCodes.Ldc_I4_S, (object)number),
});
}
public static CodeInstruction LoadConstant(int number)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
if (number >= -128 && number <= 127)
{
return LoadConstant(Convert.ToSByte(number));
}
return new CodeInstruction(OpCodes.Ldc_I4, (object)number);
}
public static CodeInstruction LoadConstant(long number)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
return new CodeInstruction(OpCodes.Ldc_I8, (object)number);
}
public static CodeInstruction LoadConstant(Enum e)
{
return (CodeInstruction)(e.GetTypeCode() switch
{
TypeCode.Int64 => LoadConstant(Convert.ToInt64(e)),
TypeCode.SByte => LoadConstant(Convert.ToSByte(e)),
_ => LoadConstant(Convert.ToInt32(e)),
});
}
public static CodeInstruction[] LoadLongOptimally(long number)
{
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Expected O, but got Unknown
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Expected O, but got Unknown
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Expected O, but got Unknown
if (number >= -128)
{
if (number <= 127)
{
return (CodeInstruction[])(object)new CodeInstruction[2]
{
LoadConstant(Convert.ToSByte(number)),
new CodeInstruction(OpCodes.Conv_I8, (object)null)
};
}
if (number <= int.MaxValue)
{
goto IL_0047;
}
}
else if (number >= int.MinValue)
{
goto IL_0047;
}
return (CodeInstruction[])(object)new CodeInstruction[1]
{
new CodeInstruction(OpCodes.Ldc_I8, (object)number)
};
IL_0047:
return (CodeInstruction[])(object)new CodeInstruction[2]
{
LoadConstant(Convert.ToInt32(number)),
new CodeInstruction(OpCodes.Conv_I8, (object)null)
};
}
public static CodeInstruction[] LoadEnumOptimally(Enum e)
{
return e.GetTypeCode() switch
{
TypeCode.Int64 => LoadLongOptimally(Convert.ToInt64(e)),
TypeCode.SByte => (CodeInstruction[])(object)new CodeInstruction[1] { LoadConstant(Convert.ToSByte(e)) },
_ => (CodeInstruction[])(object)new CodeInstruction[1] { LoadConstant(Convert.ToInt32(e)) },
};
}
public static CodeInstruction LoadString(string str)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
return new CodeInstruction(OpCodes.Ldstr, (object)str);
}
public static CodeInstruction LoadNull()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
return new CodeInstruction(OpCodes.Ldnull, (object)null);
}
public static bool LoadsNull(this CodeInstruction code)
{
return object.Equals(code.opcode, OpCodes.Ldnull);
}
public static bool LoadsProperty(this CodeInstruction code, PropertyInfo property)
{
return CodeInstructionExtensions.Calls(code, property.GetGetMethod(nonPublic: true));
}
public static bool LoadsProperty(this CodeInstruction code, Type type, string name)
{
PropertyInfo propertyInfo = AccessTools.DeclaredProperty(type, name);
if (propertyInfo != null)
{
return code.LoadsProperty(propertyInfo);
}
return false;
}
public static bool StoresProperty(this CodeInstruction code, PropertyInfo property)
{
return CodeInstructionExtensions.Calls(code, property.GetSetMethod(nonPublic: true));
}
public static bool StoresProperty(this CodeInstruction code, Type type, string name)
{
PropertyInfo propertyInfo = AccessTools.DeclaredProperty(type, name);
if (propertyInfo != null)
{
return code.StoresProperty(propertyInfo);
}
return false;
}
public static CodeInstruction LoadProperty(PropertyInfo property)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected O, but got Unknown
return new CodeInstruction(OpCodes.Call, (object)property.GetGetMethod(nonPublic: true));
}
public static CodeInstruction LoadProperty(Type type, string name)
{
PropertyInfo property = AccessTools.Property(type, name) ?? throw new ArgumentException($"No property found for type={type}, name={name}");
return LoadProperty(property);
}
public static CodeInstruction StoreProperty(PropertyInfo property)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected O, but got Unknown
return new CodeInstruction(OpCodes.Call, (object)property.GetSetMethod(nonPublic: true));
}
public static CodeInstruction StoreProperty(Type type, string name)
{
PropertyInfo property = AccessTools.Property(type, name) ?? throw new ArgumentException($"No property found for type={type}, name={name}");
return StoreProperty(property);
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}