void EmitEpilogue(IILEmitter emitter, InjectedFeature feature, NetfuserEvent.CilBodyBuilding me, IReadOnlyList <Tuple <Instruction, Var> > returns) { var target = me.Target; var rt = returns.RandomElementOrDefault(Rng); if (rt == null) { if (target.HasReturnType && (feature.Output.Flags & VarFlags.Ret) == 0) { Utils.RandomConst(emitter, target.ReturnType, Rng); } emitter.Emit(OpCodes.Ret); } else { if (target.HasReturnType) { if ((feature.Output.Flags & VarFlags.Ret) == 0) { Utils.RandomConst(emitter, target.ReturnType, Rng); } rt.Item2.Store(emitter); } emitter.Emit(OpCodes.Br, rt.Item1); } }
private CilBodyMerger(ContextImpl context, Importer importer, TypeMapping tm, MethodDef sourceMethod, MethodDef targetMethod) : base(context, importer) { _sourceMethod = sourceMethod; _targetMethod = targetMethod; _tm = tm; _instrMap = new Dictionary <Instruction, Instruction>(); _event = new NetfuserEvent.CilBodyBuilding(context, _tm, _sourceMethod, _targetMethod, Importer, _instrMap); }
IReadOnlyList <Tuple <Instruction, Var> > ScanReturns(NetfuserEvent.CilBodyBuilding me) { var result = new List <Tuple <Instruction, Var> >(); var block = me.ParseBlocks().EnumRegular().FirstOrDefault(); if (block != null) { var c = block.Fragment.Count; var hasRet = me.Target.HasReturnType; for (var i = 0; i < c; i++) { var instr = block.Fragment.Instructions[i]; if (instr.OpCode.Code == Code.Ret) { if (!hasRet) { result.Add(Tuple.Create(instr, (Var)null)); } else if (i > 0) { instr = block.Fragment.Instructions[i - 1]; if (instr.IsLdloc()) { result.Add(Tuple.Create(instr, (Var) new Var.Loc(instr.GetLocal(me.Locals)))); } else if (instr.OpCode.Code == Code.Ldfld && i > 1) { result.Add(Tuple.Create(block.Fragment.Instructions[i - 2], (Var) new Var.Fld((IField)instr.Operand, null))); } } } } } return(result); }