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);
            }
        }
Пример #2
0
 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);
        }