private static void RegisterLoggerUnsafe(List <ParseToken> validator, string linebreakIndent, CallbackActionDelegate callback) { DynamicMethod dynLog = new DynamicMethod("LogWrite" + callbackCount, typeof(void), new[] { typeof(LogHelper) }, typeof(Log), true); var ilGen = dynLog.GetILGenerator(); var localStrb = ilGen.DeclareLocal(typeof(StringBuilder)); // common type arrays Type[] argsString = { typeof(string) }; Type[] argsInt = { typeof(int) }; // common InfosTypes MethodInfo miStringBuilder_Append_String = typeof(StringBuilder).GetMethod(nameof(StringBuilder.Append), argsString); MethodInfo miLog_GenLogLevelSpaced = typeof(LogHelper).GetMethod(nameof(LogHelper.GenLogLevelSpaced)); MethodInfo miLog_GenDateFormatted = typeof(LogHelper).GetMethod(nameof(LogHelper.GenDateFormatted)); MethodInfo miLog_GenErrorTextFormatted = typeof(LogHelper).GetMethod(nameof(LogHelper.GenErrorTextFormatted), argsInt); MethodInfo miLog_GenStackTraceFormatted = typeof(LogHelper).GetMethod(nameof(LogHelper.GenStackTraceFormatted), argsInt); // prepare callback invoke ilGen.Emit(OpCodes.Ldsfld, typeof(Log).GetField(nameof(callbackAction), BindingFlags.NonPublic | BindingFlags.Static)); ilGen.Emit(OpCodes.Ldc_I4, callbackCount); ilGen.Emit(OpCodes.Ldelem_Ref); // Load stringbuilder ilGen.Emit(OpCodes.Newobj, typeof(StringBuilder).GetConstructor(Type.EmptyTypes)); ilGen.Emit(OpCodes.Stloc, localStrb); ilGen.Emit(OpCodes.Ldloc, localStrb); foreach (var part in validator) { switch (part.TokenType) { case MethodBuildToken.Text: ilGen.Emit(OpCodes.Ldstr, (string)part.Value); break; case MethodBuildToken.LogLevelSpaced: ilGen.Emit(OpCodes.Ldarg_0); ilGen.EmitCall(OpCodes.Callvirt, miLog_GenLogLevelSpaced, null); break; case MethodBuildToken.ErrorTextFormatted: ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldc_I4_0); ilGen.EmitCall(OpCodes.Callvirt, miLog_GenErrorTextFormatted, null); break; case MethodBuildToken.DateFormatted: ilGen.Emit(OpCodes.Ldarg_0); ilGen.EmitCall(OpCodes.Callvirt, miLog_GenDateFormatted, null); break; case MethodBuildToken.StackFormatted: ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldc_I4_M1); ilGen.EmitCall(OpCodes.Callvirt, miLog_GenStackTraceFormatted, null); break; default: throw new InvalidProgramException("Undefined MethodBuildToken occoured"); } ilGen.EmitCall(OpCodes.Callvirt, miStringBuilder_Append_String, null); } // call ToString and the callback method ilGen.EmitCall(OpCodes.Callvirt, typeof(StringBuilder).GetMethod(nameof(StringBuilder.ToString), Type.EmptyTypes), null); ilGen.EmitCall(OpCodes.Callvirt, typeof(CallbackActionDelegate).GetMethod(nameof(CallbackActionDelegate.Invoke), argsString), null); ilGen.Emit(OpCodes.Ret); lock (writeLock) { // Redim the calllist array if (callbackProcessor == null) { callbackProcessor = new CallbackProcessorDelegate[1]; callbackAction = new CallbackActionDelegate[1]; } else { CallbackProcessorDelegate[] tempProcessorArray = new CallbackProcessorDelegate[callbackCount + 1]; CallbackActionDelegate[] tempActionArray = new CallbackActionDelegate[callbackCount + 1]; Array.Copy(callbackProcessor, tempProcessorArray, callbackCount); Array.Copy(callbackAction, tempActionArray, callbackCount); callbackProcessor = tempProcessorArray; callbackAction = tempActionArray; } //Store event call in the calllist callbackProcessor[callbackCount] = (CallbackProcessorDelegate)dynLog.CreateDelegate(typeof(CallbackProcessorDelegate)); callbackAction[callbackCount] = callback; callbackCount++; } }
private static void RegisterLoggerUnsafe(List<ParseToken> validator, string linebreakIndent, CallbackActionDelegate callback) { DynamicMethod dynLog = new DynamicMethod("LogWrite" + callbackCount, typeof(void), new[] { typeof(LogHelper) }, typeof(Log), true); var ilGen = dynLog.GetILGenerator(); var localStrb = ilGen.DeclareLocal(typeof(StringBuilder)); // common type arrays Type[] argsString = { typeof(string) }; Type[] argsInt = { typeof(int) }; // common InfosTypes MethodInfo miStringBuilder_Append_String = typeof(StringBuilder).GetMethod(nameof(StringBuilder.Append), argsString); MethodInfo miLog_GenLogLevelSpaced = typeof(LogHelper).GetMethod(nameof(LogHelper.GenLogLevelSpaced)); MethodInfo miLog_GenDateFormatted = typeof(LogHelper).GetMethod(nameof(LogHelper.GenDateFormatted)); MethodInfo miLog_GenErrorTextFormatted = typeof(LogHelper).GetMethod(nameof(LogHelper.GenErrorTextFormatted), argsInt); MethodInfo miLog_GenStackTraceFormatted = typeof(LogHelper).GetMethod(nameof(LogHelper.GenStackTraceFormatted), argsInt); // prepare callback invoke ilGen.Emit(OpCodes.Ldsfld, typeof(Log).GetField(nameof(callbackAction), BindingFlags.NonPublic | BindingFlags.Static)); ilGen.Emit(OpCodes.Ldc_I4, callbackCount); ilGen.Emit(OpCodes.Ldelem_Ref); // Load stringbuilder ilGen.Emit(OpCodes.Newobj, typeof(StringBuilder).GetConstructor(Type.EmptyTypes)); ilGen.Emit(OpCodes.Stloc, localStrb); ilGen.Emit(OpCodes.Ldloc, localStrb); foreach (var part in validator) { switch (part.TokenType) { case MethodBuildToken.Text: ilGen.Emit(OpCodes.Ldstr, (string)part.Value); break; case MethodBuildToken.LogLevelSpaced: ilGen.Emit(OpCodes.Ldarg_0); ilGen.EmitCall(OpCodes.Callvirt, miLog_GenLogLevelSpaced, null); break; case MethodBuildToken.ErrorTextFormatted: ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldc_I4_0); ilGen.EmitCall(OpCodes.Callvirt, miLog_GenErrorTextFormatted, null); break; case MethodBuildToken.DateFormatted: ilGen.Emit(OpCodes.Ldarg_0); ilGen.EmitCall(OpCodes.Callvirt, miLog_GenDateFormatted, null); break; case MethodBuildToken.StackFormatted: ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldc_I4_M1); ilGen.EmitCall(OpCodes.Callvirt, miLog_GenStackTraceFormatted, null); break; default: throw new InvalidProgramException("Undefined MethodBuildToken occoured"); } ilGen.EmitCall(OpCodes.Callvirt, miStringBuilder_Append_String, null); } // call ToString and the callback method ilGen.EmitCall(OpCodes.Callvirt, typeof(StringBuilder).GetMethod(nameof(StringBuilder.ToString), Type.EmptyTypes), null); ilGen.EmitCall(OpCodes.Callvirt, typeof(CallbackActionDelegate).GetMethod(nameof(CallbackActionDelegate.Invoke), argsString), null); ilGen.Emit(OpCodes.Ret); lock (writeLock) { // Redim the calllist array if (callbackProcessor == null) { callbackProcessor = new CallbackProcessorDelegate[1]; callbackAction = new CallbackActionDelegate[1]; } else { CallbackProcessorDelegate[] tempProcessorArray = new CallbackProcessorDelegate[callbackCount + 1]; CallbackActionDelegate[] tempActionArray = new CallbackActionDelegate[callbackCount + 1]; Array.Copy(callbackProcessor, tempProcessorArray, callbackCount); Array.Copy(callbackAction, tempActionArray, callbackCount); callbackProcessor = tempProcessorArray; callbackAction = tempActionArray; } //Store event call in the calllist callbackProcessor[callbackCount] = (CallbackProcessorDelegate)dynLog.CreateDelegate(typeof(CallbackProcessorDelegate)); callbackAction[callbackCount] = callback; callbackCount++; } }