internal static IEnumerable <MsilInstruction> Transpile(MethodBase baseMethod, Func <Type, MsilLocal> localCreator, IEnumerable <MethodInfo> transpilers, MsilLabel retLabel) { var context = new MethodContext(baseMethod); context.Read(); // IntegrityAnalysis(LogLevel.Trace, context.Instructions); return(Transpile(baseMethod, context.Instructions, localCreator, transpilers, retLabel)); }
internal MsilLabel LabelAt(int i) { if (Labels.TryGetValue(i, out MsilLabel label)) { return(label); } Labels.Add(i, label = new MsilLabel()); return(label); }
private static IEnumerable <MsilInstruction> FoliageRenderFix(IEnumerable <MsilInstruction> src) { foreach (var call in src) { if ((call.OpCode == OpCodes.Callvirt || call.OpCode == OpCodes.Call) && call.Operand is MsilOperandInline <MethodBase> op && op.Value == _rcDrawAuto) { var end = new MsilLabel(); var noStereo = new MsilLabel(); yield return(new MsilInstruction(OpCodes.Call).InlineValue(_stereoRenderEnable.GetMethod)); yield return(new MsilInstruction(OpCodes.Brfalse).InlineTarget(noStereo)); yield return(new MsilInstruction(OpCodes.Dup)); // [... RC, RC] yield return(new MsilInstruction(OpCodes.Call).InlineValue(_beginDrawGBufferPass)); // [... RC] yield return(new MsilInstruction(OpCodes.Dup)); // [... RC, RC] yield return(new MsilInstruction(call.OpCode).InlineValue(_rcDrawAuto)); // [... RC] yield return(new MsilInstruction(OpCodes.Dup)); // [... RC, RC] yield return(new MsilInstruction(OpCodes.Call).InlineValue(_switchDrawGBufferPass)); // [... RC] yield return(new MsilInstruction(OpCodes.Dup)); // [... RC, RC] yield return(new MsilInstruction(call.OpCode).InlineValue(_rcDrawAuto)); // [... RC] yield return(new MsilInstruction(OpCodes.Call).InlineValue(_endDrawGBufferPass)); // [...] yield return(new MsilInstruction(OpCodes.Br).InlineTarget(end)); call.Labels.Add(noStereo); yield return(call); var t = new MsilInstruction(OpCodes.Nop); t.Labels.Add(end); yield return(t); } else { yield return(call); } } }
private static IEnumerable <MsilInstruction> FixDrawCalls(IEnumerable <MsilInstruction> src) { foreach (var call in src) { if ((call.OpCode == OpCodes.Callvirt || call.OpCode == OpCodes.Call) && call.Operand is MsilOperandInline <MethodBase> op && _stereoCallReplace.TryGetValue(op.Value, out MethodBase replaceTarget)) { var end = new MsilLabel(); var noStereo = new MsilLabel(); yield return(new MsilInstruction(OpCodes.Call).InlineValue(_stereoRenderEnable.GetMethod)); yield return(new MsilInstruction(OpCodes.Brfalse).InlineTarget(noStereo)); yield return(new MsilInstruction(OpCodes.Call).InlineValue(replaceTarget)); yield return(new MsilInstruction(OpCodes.Br).InlineTarget(end)); call.Labels.Add(noStereo); yield return(call); var t = new MsilInstruction(OpCodes.Nop); t.Labels.Add(end); yield return(t); }
private IEnumerable <MsilInstruction> EmitPatched(Func <Type, bool, MsilLocal> declareLocal) { var methodBody = _method.GetMethodBody(); Debug.Assert(methodBody != null, "Method body is null"); foreach (var localVar in methodBody.LocalVariables) { Debug.Assert(localVar.LocalType != null); declareLocal(localVar.LocalType, localVar.IsPinned); } var instructions = new List <MsilInstruction>(); var specialVariables = new Dictionary <string, MsilLocal>(); var labelAfterOriginalContent = new MsilLabel(); var labelSkipMethodContent = new MsilLabel(); Type returnType = _method is MethodInfo meth ? meth.ReturnType : typeof(void); MsilLocal resultVariable = null; if (returnType != typeof(void)) { if (Prefixes.Concat(Suffixes).SelectMany(x => x.GetParameters()).Any(x => x.Name == RESULT_PARAMETER) || Prefixes.Any(x => x.ReturnType == typeof(bool))) { resultVariable = declareLocal(returnType, false); } } if (resultVariable != null) { instructions.AddRange(resultVariable.SetToDefault()); } MsilLocal prefixSkippedVariable = null; if (Prefixes.Count > 0 && Suffixes.Any(x => x.GetParameters() .Any(y => y.Name.Equals(PREFIX_SKIPPED_PARAMETER)))) { prefixSkippedVariable = declareLocal(typeof(bool), false); specialVariables.Add(PREFIX_SKIPPED_PARAMETER, prefixSkippedVariable); } if (resultVariable != null) { specialVariables.Add(RESULT_PARAMETER, resultVariable); } // Create special variables foreach (var m in Prefixes.Concat(Suffixes)) { foreach (var param in m.GetParameters()) { if (param.Name.StartsWith(LOCAL_PARAMETER)) { var requiredType = param.ParameterType.IsByRef ? param.ParameterType.GetElementType() : param.ParameterType; if (specialVariables.TryGetValue(param.Name, out var existingParam)) { if (existingParam.Type != requiredType) { throw new ArgumentException( $"Trying to use injected local {param.Name} for {m.DeclaringType?.FullName}#{m.ToString()} with type {requiredType} but a local with the same name already exists with type {existingParam.Type}", param.Name); } } else { specialVariables.Add(param.Name, declareLocal(requiredType, false)); } } } } foreach (MethodInfo prefix in Prefixes) { instructions.AddRange(EmitMonkeyCall(prefix, specialVariables)); if (prefix.ReturnType == typeof(bool)) { instructions.Add(new MsilInstruction(OpCodes.Brfalse).InlineTarget(labelSkipMethodContent)); } else if (prefix.ReturnType != typeof(void)) { throw new Exception( $"Prefixes must return void or bool. {prefix.DeclaringType?.FullName}.{prefix.Name} returns {prefix.ReturnType}"); } } instructions.AddRange(MethodTranspiler.Transpile(_method, (x) => declareLocal(x, false), Transpilers, labelAfterOriginalContent)); instructions.Add(new MsilInstruction(OpCodes.Nop).LabelWith(labelAfterOriginalContent)); if (resultVariable != null) { instructions.Add(new MsilInstruction(OpCodes.Stloc).InlineValue(resultVariable)); } var notSkip = new MsilLabel(); instructions.Add(new MsilInstruction(OpCodes.Br).InlineTarget(notSkip)); instructions.Add(new MsilInstruction(OpCodes.Nop).LabelWith(labelSkipMethodContent)); if (prefixSkippedVariable != null) { instructions.Add(new MsilInstruction(OpCodes.Ldc_I4_1)); instructions.Add(new MsilInstruction(OpCodes.Stloc).InlineValue(prefixSkippedVariable)); } instructions.Add(new MsilInstruction(OpCodes.Nop).LabelWith(notSkip)); foreach (MethodInfo suffix in Suffixes) { instructions.AddRange(EmitMonkeyCall(suffix, specialVariables)); if (suffix.ReturnType != typeof(void)) { throw new Exception($"Suffixes must return void. {suffix.DeclaringType?.FullName}.{suffix.Name} returns {suffix.ReturnType}"); } } if (resultVariable != null) { instructions.Add(new MsilInstruction(OpCodes.Ldloc).InlineValue(resultVariable)); } instructions.Add(new MsilInstruction(OpCodes.Ret)); var result = MethodTranspiler.Transpile(_method, instructions, (x) => declareLocal(x, false), PostTranspilers, null).ToList(); if (result.Last().OpCode != OpCodes.Ret) { result.Add(new MsilInstruction(OpCodes.Ret)); } return(result); }
private static IEnumerable <MsilInstruction> FixBranchAndReturn(IEnumerable <MsilInstruction> insn, MsilLabel retTarget) { foreach (MsilInstruction i in insn) { if (retTarget != null && i.OpCode == OpCodes.Ret) { var j = i.CopyWith(OpCodes.Br).InlineTarget(retTarget); _log.Trace($"Replacing {i} with {j}"); yield return(j); } else if (_shortToLongBranch.TryGetValue(i.OpCode, out OpCode replaceOpcode)) { var result = i.CopyWith(replaceOpcode); _log.Trace($"Replacing {i} with {result}"); yield return(result); } else { yield return(i); } } }
internal static IEnumerable <MsilInstruction> Transpile(MethodBase baseMethod, IEnumerable <MsilInstruction> methodContent, Func <Type, MsilLocal> localCreator, IEnumerable <MethodInfo> transpilers, MsilLabel retLabel) { foreach (MethodInfo transpiler in transpilers) { var paramList = new List <object>(); foreach (var parameter in transpiler.GetParameters()) { if (parameter.Name.Equals("__methodBody")) { paramList.Add(baseMethod.GetMethodBody()); } else if (parameter.Name.Equals("__methodBase")) { paramList.Add(baseMethod); } else if (parameter.Name.Equals("__localCreator")) { paramList.Add(localCreator); } else if (parameter.ParameterType == typeof(IEnumerable <MsilInstruction>)) { paramList.Add(methodContent); } else { throw new ArgumentException( $"Bad transpiler parameter type {parameter.ParameterType.FullName} {parameter.Name}"); } } methodContent = (IEnumerable <MsilInstruction>)transpiler.Invoke(null, paramList.ToArray()); } return(FixBranchAndReturn(methodContent, retLabel)); }
private static IEnumerable <MsilInstruction> TranspileDrawF(IEnumerable <MsilInstruction> stream, Func <Type, MsilLocal> __localCreator) { var replaced = false; foreach (var insn in stream) { if (AllowUiHack && insn.Operand is MsilOperandInline <MethodBase> mtarget && mtarget.Value == _drawSprites) { var stereoMode = new MsilLabel(); var endOfSprites = new MsilLabel(); yield return(new MsilInstruction(OpCodes.Call).InlineValue(_stereoRenderEnable.GetMethod)); yield return(new MsilInstruction(OpCodes.Brtrue).InlineTarget(stereoMode)); // if (!Stereo.Enable) { yield return(insn); yield return(new MsilInstruction(OpCodes.Br).InlineTarget(endOfSprites)); } // else { yield return(new MsilInstruction(OpCodes.Nop).LabelWith(stereoMode)); // Clear out arguments if (!_drawSprites.IsStatic) { yield return(new MsilInstruction(OpCodes.Pop)); } foreach (var k in _drawSprites.GetParameters()) { yield return(new MsilInstruction(OpCodes.Pop)); } // Create the RTV var uiRtv = __localCreator.Invoke(_drawSpritesOffscreen.ReturnType); yield return(new MsilInstruction(OpCodes.Ldstr).InlineValue("VR.Overlay")); #region viewport.X / 2 yield return(new MsilInstruction(OpCodes.Call).InlineValue(_viewportResolution.GetMethod)); yield return(new MsilInstruction(OpCodes.Ldfld).InlineValue(_vector2IX)); yield return(new MsilInstruction(OpCodes.Ldc_I4_2)); yield return(new MsilInstruction(OpCodes.Div)); #endregion #region viewport.Y yield return(new MsilInstruction(OpCodes.Call).InlineValue(_viewportResolution.GetMethod)); yield return(new MsilInstruction(OpCodes.Ldfld).InlineValue(_vector2IY)); #endregion yield return(new MsilInstruction(OpCodes.Ldc_I4).InlineValue((int)SharpDX.DXGI.Format .B8G8R8A8_UNorm)); #region (SharpDX.Color?)null var tmpColorNullable = __localCreator.Invoke(typeof(SharpDX.Color?)); yield return(tmpColorNullable.AsReferenceLoad()); yield return(new MsilInstruction(OpCodes.Initobj).InlineValue(tmpColorNullable.Type)); yield return(tmpColorNullable.AsValueLoad()); #endregion yield return(new MsilInstruction(OpCodes.Call).InlineValue(_drawSpritesOffscreen)); yield return(uiRtv.AsValueStore()); var tmpViewportNullable = __localCreator.Invoke(typeof(MyViewport?)); yield return(tmpViewportNullable.AsReferenceLoad()); yield return(new MsilInstruction(OpCodes.Initobj).InlineValue(tmpViewportNullable.Type)); foreach (var region in new[] { Types.StereoRenderRegion.Left, Types.StereoRenderRegion.Right }) { yield return(new MsilInstruction(OpCodes.Call).InlineValue(_backbuffer.GetMethod)); yield return(uiRtv.AsValueLoad()); yield return(new MsilInstruction(OpCodes.Ldc_I4_1)); yield return(tmpViewportNullable.AsValueLoad()); // MyStereoRender.RenderRegion = region yield return(new MsilInstruction(OpCodes.Ldc_I4).InlineValue((int)region)); yield return(new MsilInstruction(OpCodes.Stsfld).InlineValue(_stereoRenderRegion)); // MyCopyToRtv.Run(MyRender11.Backbuffer, tempBindable, true, null) yield return(new MsilInstruction(OpCodes.Call).InlineValue(_copyToRtv)); } // MyStereoRender.RenderRegion = StereoRenderRegion.Fullscreen yield return(new MsilInstruction(OpCodes.Ldc_I4).InlineValue((int)Types.StereoRenderRegion .Fullscreen)); yield return(new MsilInstruction(OpCodes.Stsfld).InlineValue(_stereoRenderRegion)); yield return(uiRtv.AsValueLoad()); yield return(new MsilInstruction(OpCodes.Callvirt).InlineValue(_releaseTexture)); } yield return(new MsilInstruction(OpCodes.Nop).LabelWith(endOfSprites)); } else if (!replaced && insn.Operand is MsilOperandInline <FieldInfo> target && target.Value == _renderScreenshot) { var endOfDisplay = new MsilLabel(); yield return(new MsilInstruction(OpCodes.Call).InlineValue(_openvrStatic.GetMethod)); yield return(new MsilInstruction(OpCodes.Brfalse).InlineTarget(endOfDisplay)); // if (OpenVR.Static != null) { yield return(new MsilInstruction(OpCodes.Ldsfld).InlineValue(_gbufferMain)); yield return(new MsilInstruction(OpCodes.Call).InlineValue(_colorBlack.GetMethod)); yield return(new MsilInstruction(OpCodes.Callvirt).InlineValue(_gbufferClear)); // GBuffer.Main.Clear(Color.Black); yield return(new MsilInstruction(OpCodes.Call).InlineValue(_openvrStatic.GetMethod)); yield return(new MsilInstruction(OpCodes.Call).InlineValue(_backbuffer.GetMethod)); yield return(new MsilInstruction(OpCodes.Callvirt).InlineValue(_backbufferResource.GetMethod)); yield return(new MsilInstruction(OpCodes.Callvirt).InlineValue(_resourcePointer.GetMethod)); yield return(new MsilInstruction(OpCodes.Callvirt).InlineValue(_openvrDisplayEye)); // OpenVR.Static.DisplayEye(Backbuffer.Resource.NativePointer); } replaced = true; var copy = insn.CopyWith(insn.OpCode); copy.Labels.Add(endOfDisplay); yield return(copy); } else { yield return(insn); } } }
private static IEnumerable <MsilInstruction> MoveAmbientOcclusionOutOfLoop( IEnumerable <MsilInstruction> instructionStream) { var labelPosition = new Dictionary <MsilLabel, int>(); var body = instructionStream.ToList(); var positionBeginAo = -1; var positionEndAo = -1; var positionAsFullscreen = -1; for (var i = 0; i < body.Count; i++) { var ins = body[i]; foreach (var k in ins.Labels) { labelPosition.Add(k, i); } if (ins.OpCode == OpCodes.Stsfld && ins.Operand is MsilOperandInline <FieldInfo> fieldInfo && fieldInfo.Value == _stereoRenderRegion && i > 0 && body[i - 1].IsConstIntLoad() && body[i - 1].GetConstInt() == (int)Types.StereoRenderRegion.Fullscreen) { positionAsFullscreen = i; } if (ins.OpCode == OpCodes.Ldstr && ins.Operand is MsilOperandInline <string> inStr && inStr.Value.Equals("SSAO")) { // Advance back up until we find the end of the previous block. var j = i; while (j-- > 0) { if (body[j].Operand is MsilOperandInline <MethodBase> operand && operand.Value == _gpuProfilerEndBlock) { positionBeginAo = j + 1; break; } } j = i; MsilLabel endLabel = null; while (++j < body.Count) { if (body[j].OpCode == OpCodes.Br || body[j].OpCode == OpCodes.Br_S) { endLabel = ((MsilOperandBrTarget)body[j].Operand).Target; break; } } while (++j < body.Count) { if (body[j].Labels.Contains(endLabel)) { positionEndAo = j; } } } } if (positionEndAo == -1 || positionBeginAo == -1 || positionAsFullscreen == -1) { foreach (var k in body) { yield return(k); } yield break; } for (var i = 0; i < body.Count; i++) { if (i < positionBeginAo) { yield return(body[i]); } else if (i >= positionEndAo) { yield return(body[i]); } if (i == positionAsFullscreen) { var endOfAo = new MsilLabel(); for (var j = positionBeginAo; j < positionEndAo; j++) { if (body[j].Operand is MsilOperandBrTarget target) { var tiv = labelPosition[target.Target]; if (tiv == positionEndAo) { yield return(body[j].CopyWith(body[j].OpCode).InlineTarget(endOfAo)); continue; } else if (tiv > positionEndAo || tiv < positionBeginAo) { _log.Warn($"Unable to figure out how to deal with label {target.Target} at {tiv}. AO data is from {positionBeginAo}-{positionEndAo}"); } } yield return(body[j]); } var temp = new MsilInstruction(OpCodes.Nop); temp.Labels.Add(endOfAo); yield return(temp); } } }
private static IEnumerable <MsilInstruction> TranspilerForUpdate <T>(IEnumerable <MsilInstruction> insn, Func <Type, MsilLocal> __localCreator, MethodBase __methodBase) { MethodInfo profilerCall = null; if (typeof(IMyEntity).IsAssignableFrom(typeof(T))) { profilerCall = ProfilerData.GetEntityProfiler; } else if (typeof(MyEntityComponentBase).IsAssignableFrom(typeof(T)) || typeof(T) == typeof(IMyGameLogicComponent)) { profilerCall = ProfilerData.GetEntityComponentProfiler; } else if (typeof(MyCubeGridSystems) == typeof(T)) { profilerCall = ProfilerData.GetGridSystemProfiler; } else if (typeof(MySessionComponentBase) == typeof(T)) { profilerCall = ProfilerData.GetSessionComponentProfiler; } else { _log.Warn($"Trying to profile unknown target {typeof(T)}"); } MsilLocal profilerEntry = profilerCall != null ? __localCreator(typeof(SlimProfilerEntry)) : null; var usedLocals = new List <MsilLocal>(); var tmpArgument = new Dictionary <Type, Stack <MsilLocal> >(); var foundAny = false; foreach (MsilInstruction i in insn) { if (profilerCall != null && (i.OpCode == OpCodes.Call || i.OpCode == OpCodes.Callvirt) && ShouldProfileMethodCall <T>((i.Operand as MsilOperandInline <MethodBase>)?.Value)) { MethodBase target = ((MsilOperandInline <MethodBase>)i.Operand).Value; ParameterInfo[] pams = target.GetParameters(); usedLocals.Clear(); foreach (ParameterInfo pam in pams) { if (!tmpArgument.TryGetValue(pam.ParameterType, out var stack)) { tmpArgument.Add(pam.ParameterType, stack = new Stack <MsilLocal>()); } MsilLocal local = stack.Count > 0 ? stack.Pop() : __localCreator(pam.ParameterType); usedLocals.Add(local); yield return(local.AsValueStore()); } _log.Debug($"Attaching profiling to {target?.DeclaringType?.FullName}#{target?.Name} in {__methodBase.DeclaringType?.FullName}#{__methodBase.Name} targeting {typeof(T)}"); yield return(new MsilInstruction(OpCodes.Dup)); // duplicate the object the update is called on if (typeof(MyCubeGridSystems) == typeof(T) && __methodBase.DeclaringType == typeof(MyCubeGridSystems)) { yield return(new MsilInstruction(OpCodes.Ldarg_0)); yield return(new MsilInstruction(OpCodes.Ldfld).InlineValue(_gridSystemsCubeGrid)); } yield return(new MsilInstruction(OpCodes.Call).InlineValue(profilerCall)); // consume object the update is called on yield return(new MsilInstruction(OpCodes.Dup)); // Duplicate profiler entry for brnull yield return(profilerEntry.AsValueStore()); // store the profiler entry for later var skipProfilerOne = new MsilLabel(); yield return(new MsilInstruction(OpCodes.Brfalse).InlineTarget(skipProfilerOne)); // Brfalse == Brnull { yield return(profilerEntry.AsValueLoad()); // start the profiler yield return(new MsilInstruction(OpCodes.Call).InlineValue(ProfilerData.ProfilerEntryStart)); } // consumes from the first Dup yield return(new MsilInstruction(OpCodes.Nop).LabelWith(skipProfilerOne)); for (int j = usedLocals.Count - 1; j >= 0; j--) { yield return(usedLocals[j].AsValueLoad()); tmpArgument[usedLocals[j].Type].Push(usedLocals[j]); } yield return(i); var skipProfilerTwo = new MsilLabel(); yield return(profilerEntry.AsValueLoad()); yield return(new MsilInstruction(OpCodes.Brfalse).InlineTarget(skipProfilerTwo)); // Brfalse == Brnull { yield return(profilerEntry.AsValueLoad()); // stop the profiler yield return(new MsilInstruction(OpCodes.Call).InlineValue(ProfilerData.ProfilerEntryStop)); } yield return(new MsilInstruction(OpCodes.Nop).LabelWith(skipProfilerTwo)); foundAny = true; continue; } yield return(i); } if (!foundAny) { _log.Warn($"Didn't find any update profiling targets for target {typeof(T)} in {__methodBase.DeclaringType?.FullName}#{__methodBase.Name}"); } }
private static IEnumerable <MsilInstruction> TranspileSingleMethod(IEnumerable <MsilInstruction> insn, Func <Type, MsilLocal> __localCreator, MethodBase __methodBase) { MethodInfo profilerCall = null; foreach (var method in typeof(ProfilerData).GetMethods(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)) { if (IsSingleMethodProfilerCall(__methodBase, method)) { profilerCall = method; break; } } if (profilerCall == null) { foreach (var method in typeof(ProfilerPatch).GetMethods(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)) { if (IsSingleMethodProfilerCall(__methodBase, method)) { profilerCall = method; break; } } } if (profilerCall == null) { _log.Warn($"Single method profiler for {__methodBase.DeclaringType?.FullName}#{__methodBase.Name} couldn't find a profiler call; will not operate"); } FieldInfo stringPool = typeof(ProfilerPatch).GetField(nameof(_keyedStringPool), BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); if (stringPool == null) { _log.Warn($"Single method profiler for {__methodBase.DeclaringType?.FullName}#{__methodBase.Name} couldn't file string pool; will not operate"); } if (profilerCall == null || stringPool == null) { foreach (var i in insn) { yield return(i); } yield break; } // Reserve a keyed string. int stringKey = 0; lock (_keyedStringPoolLock) { while (_usedStrings >= _keyedStringPool.Length) { Array.Resize(ref _keyedStringPool, Math.Max(64, _keyedStringPool.Length * 2)); } stringKey = _usedStrings; _keyedStringPool[stringKey] = __methodBase.Name; _usedStrings++; } var profilerLocal = __localCreator(typeof(SlimProfilerEntry)); _log.Debug($"Attaching profiling to {__methodBase?.DeclaringType?.FullName}#{__methodBase?.Name} with profiler call {profilerCall.DeclaringType?.FullName}#{profilerCall}"); var labelNoProfiling = new MsilLabel(); var labelStoreProfiling = new MsilLabel(); yield return(new MsilInstruction(OpCodes.Ldsfld).InlineValue(ProfilerData.FieldProfileSingleMethods)); yield return(new MsilInstruction(OpCodes.Brfalse).InlineTarget(labelNoProfiling)); { // if (ProfilerData.FieldProfileSingleMethods) foreach (var stub in EmitSingleMethodProfilerCall(__methodBase, profilerCall, stringPool, stringKey)) { yield return(stub); } yield return(new MsilInstruction(OpCodes.Br).InlineTarget(labelStoreProfiling)); } { // else yield return(new MsilInstruction(OpCodes.Ldnull).LabelWith(labelNoProfiling)); } yield return(new MsilInstruction(OpCodes.Dup).LabelWith(labelStoreProfiling)); // Duplicate profiler entry for brnull yield return(profilerLocal.AsValueStore()); // store the profiler entry for later var skipProfilerOne = new MsilLabel(); yield return(new MsilInstruction(OpCodes.Brfalse).InlineTarget(skipProfilerOne)); { // if (profiler != null) yield return(profilerLocal.AsValueLoad()); yield return(new MsilInstruction(OpCodes.Call).InlineValue(ProfilerData.ProfilerEntryStart)); } // consumes from the first Dup yield return(new MsilInstruction(OpCodes.Nop).LabelWith(skipProfilerOne)); var skipMainMethod = new MsilLabel(); foreach (var i in insn) { if (i.OpCode == OpCodes.Ret) { MsilInstruction j = new MsilInstruction(OpCodes.Br).InlineTarget(skipMainMethod); foreach (MsilLabel l in i.Labels) { j.Labels.Add(l); } yield return(j); } else { yield return(i); } } var skipProfilerTwo = new MsilLabel(); yield return(profilerLocal.AsValueLoad().LabelWith(skipMainMethod)); yield return(new MsilInstruction(OpCodes.Brfalse).InlineTarget(skipProfilerTwo)); // Brfalse == Brnull { yield return(profilerLocal.AsValueLoad()); // stop the profiler yield return(new MsilInstruction(OpCodes.Call).InlineValue(ProfilerData.ProfilerEntryStop)); } yield return(new MsilInstruction(OpCodes.Nop).LabelWith(skipProfilerTwo)); }