#if REFLECTION_EMIT_COMPILER #if DEBUG using System.Reflection.Emit; using System.Reflection; using System; using System.Diagnostics; namespace FastReport.Code.Expressions { internal sealed class ILGeneratorDebugger { private readonly ILGenerator _ilGenerator; public ILGeneratorDebugger(ILGenerator iLGenerator) { _ilGenerator = iLGenerator; } private void ToConsole(OpCode opcode) { string msg = $"IL_{_ilGenerator.ILOffset.ToString("X")}: {opcode.ToString()}"; //Console.WriteLine(msg); Debug.WriteLine(msg); } private void ToConsole(OpCode opcode, object arg) { string argString; if(arg.GetType() == typeof(string)) { argString = $"\"{arg}\""; } else argString = arg.ToString(); string msg = $"IL_{_ilGenerator.ILOffset.ToString("X")}: {opcode.ToString()} {argString}"; //Console.WriteLine(msg); Debug.WriteLine(msg); } public void Emit(OpCode opcode) { ToConsole(opcode); _ilGenerator.Emit(opcode); } public void Emit(OpCode opcode, byte arg) { ToConsole(opcode, arg); _ilGenerator.Emit(opcode, arg); } public void Emit(OpCode opcode, sbyte arg) { ToConsole(opcode, arg); _ilGenerator.Emit(opcode, arg); } public void Emit(OpCode opcode, short arg) { ToConsole(opcode, arg); _ilGenerator.Emit(opcode, arg); } public void Emit(OpCode opcode, int arg) { ToConsole(opcode, arg); _ilGenerator.Emit(opcode, arg); } public void Emit(OpCode opcode, MethodInfo meth) { _ilGenerator.Emit(opcode, meth); } public void EmitCalli(OpCode opcode, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Type[] optionalParameterTypes) { _ilGenerator.EmitCalli(opcode, callingConvention, returnType, parameterTypes, optionalParameterTypes); } //public void EmitCalli(OpCode opcode, CallingConvention unmanagedCallConv, Type? returnType, Type[]? parameterTypes) //{ // _ilGenerator.EmitCalli(opcode, unmanagedCallConv, returnType, parameterTypes); //} public void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[] optionalParameterTypes) { ToConsole(opcode, methodInfo); _ilGenerator.EmitCall(opcode, methodInfo, optionalParameterTypes); } public void Emit(OpCode opcode, SignatureHelper signature) { _ilGenerator.Emit(opcode, signature); } public void Emit(OpCode opcode, ConstructorInfo con) { _ilGenerator.Emit(opcode, con); } public void Emit(OpCode opcode, Type cls) { ToConsole(opcode, cls); _ilGenerator.Emit(opcode, cls); } public void Emit(OpCode opcode, long arg) { ToConsole(opcode, arg); _ilGenerator.Emit(opcode, arg); } public void Emit(OpCode opcode, float arg) { ToConsole(opcode, arg); _ilGenerator.Emit(opcode, arg); } public void Emit(OpCode opcode, double arg) { ToConsole(opcode, arg); _ilGenerator.Emit(opcode, arg); } public void Emit(OpCode opcode, Label label) { ToConsole(opcode, "label #" + label.GetHashCode()); _ilGenerator.Emit(opcode, label); } public void Emit(OpCode opcode, Label[] labels) { _ilGenerator.Emit(opcode, labels); } public void Emit(OpCode opcode, FieldInfo field) { ToConsole(opcode, field); _ilGenerator.Emit(opcode, field); } public void Emit(OpCode opcode, string str) { ToConsole(opcode, str); _ilGenerator.Emit(opcode, str); } public void Emit(OpCode opcode, LocalBuilder local) { ToConsole(opcode, local); _ilGenerator.Emit(opcode, local); } #region Exceptions public Label BeginExceptionBlock() { return _ilGenerator.BeginExceptionBlock(); } public void EndExceptionBlock() { _ilGenerator.EndExceptionBlock(); } public void BeginExceptFilterBlock() { _ilGenerator.BeginExceptFilterBlock(); } public void BeginCatchBlock(Type exceptionType) { _ilGenerator.BeginCatchBlock(exceptionType); } public void BeginFaultBlock() { _ilGenerator.BeginFaultBlock(); } public void BeginFinallyBlock() { _ilGenerator.BeginFinallyBlock(); } #endregion #region Labels public Label DefineLabel() { return _ilGenerator.DefineLabel(); } public void MarkLabel(Label loc) { _ilGenerator.MarkLabel(loc); } #endregion #region IL Macros public void ThrowException(Type excType) { _ilGenerator.ThrowException(excType); } public void EmitWriteLine(string value) { _ilGenerator.EmitWriteLine(value); } public void EmitWriteLine(LocalBuilder localBuilder) { _ilGenerator.EmitWriteLine(localBuilder); } public void EmitWriteLine(FieldInfo fld) { _ilGenerator.EmitWriteLine(fld); } #endregion public LocalBuilder DeclareLocal(Type localType) { Console.WriteLine($".locals init: {localType}"); return _ilGenerator.DeclareLocal(localType); } public LocalBuilder DeclareLocal(Type localType, bool pinned) { return _ilGenerator.DeclareLocal(localType, pinned); } public void UsingNamespace(string usingNamespace) { _ilGenerator.UsingNamespace(usingNamespace); } public void BeginScope() { _ilGenerator.BeginScope(); } public void EndScope() { _ilGenerator.EndScope(); } public int ILOffset => _ilGenerator.ILOffset; } } #endif #endif