コード例 #1
0
        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
        public void EmitChecker(IRng rng, IILEmitter emitter, Instruction falseTarget)
        {
            Local local = null;

            try
            {
                var zti = IsZeroTolerant() ? rng.NextInt32(0, 2) : -1;
                if (zti >= 0 || (_upper.HasValue && _lower.HasValue))
                {
                    local = emitter.RequestTempLocal(ElementType.ToType());
                    emitter.Stloc(local);
                }

                var upperFirst = rng.NextBoolean();
                if (zti == 0)
                {
                    EmitNz();
                }
                Emit(emitter, ref local, upperFirst, rng.NextBoolean(), falseTarget);
                if (zti == 1)
                {
                    EmitNz();
                }
                Emit(emitter, ref local, !upperFirst, rng.NextBoolean(), falseTarget);
                if (zti == 2)
                {
                    EmitNz();
                }
            }
            finally
            {
                if (local != null)
                {
                    emitter.TempLocals.Release(local);
                }
            }

            void EmitNz()
            {
                emitter.Ldloc(local);
                if (rng.NextBoolean())
                {
                    emitter.Emit(OpCodes.Brfalse, falseTarget);
                }
                else
                {
                    emitter.Emit(OpCodes.Ldc_I4_0);
                    emitter.NumericConversion(ElementType.I4, ElementType, false);
                    emitter.Emit(OpCodes.Beq, falseTarget);
                }
            }
        }
コード例 #3
0
ファイル: Extensions.cs プロジェクト: dotnet-toolset/Netfuser
 public static IILEmitter Emit(this IILEmitter emitter, params OpCode[] codes)
 {
     foreach (var code in codes)
     {
         emitter.Emit(Instruction.Create(code));
     }
     return(emitter);
 }
コード例 #4
0
ファイル: Extensions.cs プロジェクト: dotnet-toolset/Netfuser
 public static IILEmitter Emit(this IILEmitter emitter, IEnumerable <Instruction> instructions)
 {
     foreach (var i in instructions)
     {
         emitter.Emit(i.Clone());
     }
     return(emitter);
 }
コード例 #5
0
        public void EmitChecker(IILEmitter emitter, IRng rng, Instruction normalFlowTarget)
        {
            var fv = Flag.Field;

            emitter.Emit(OpCodes.Ldarg_0);
            emitter.Emit(OpCodes.Ldfld, emitter.Importer.Import(fv));
            if (Constraints != null)
            {
                emitter.NumericConversion(fv.FieldType.ElementType, Constraints.ElementType, false);
                Constraints.EmitChecker(rng, emitter, normalFlowTarget);
            }
            else
            {
                var(signed, bytes) = IntConstraints.GetProps(Flag.Field.FieldType.ElementType);
                emitter.Const(Value.Value, bytes, signed);
                emitter.Emit(OpCodes.Bne_Un, normalFlowTarget);
            }
        }
コード例 #6
0
            public override void Store(IILEmitter emitter, Action pushValue = null)
            {
                if (pushValue == null)
                {
                    using (emitter.UseTempLocal(Type, out var local))
                    {
                        emitter.Stloc(local);
                        emitter.Emit(OpCodes.Ldarg_0);
                        emitter.Ldloc(local);
                    }
                }
                else
                {
                    emitter.Emit(OpCodes.Ldarg_0);
                    pushValue.Invoke();
                }

                Stfld(emitter);
            }
コード例 #7
0
 public override void Store(IILEmitter emitter, Action pushValue = null)
 {
     pushValue?.Invoke();
     if (Parameter.IsReturnTypeParameter)
     {
         emitter.Emit(OpCodes.Ret);
     }
     else
     {
         emitter.Starg(Parameter);
     }
 }
コード例 #8
0
        public static void EmitLoadArg(IILEmitter il, int index)
        {
            switch (index)
            {
            case 0:
                il.Emit(OpCodes.Ldarg_0);
                return;

            case 1:
                il.Emit(OpCodes.Ldarg_1);
                return;

            case 2:
                il.Emit(OpCodes.Ldarg_2);
                return;

            case 3:
                il.Emit(OpCodes.Ldarg_3);
                return;

            case { } n when n < 256:
                il.Emit(OpCodes.Ldarg_S, (byte)index);
                return;

            default:
                il.Emit(OpCodes.Ldarg, (short)index);
                return;
            }
        }
コード例 #9
0
        public override void Emit(IMemberEmitter member, ILGenerator gen)
        {
            ArgumentsUtil.EmitLoadOwnerAndReference(reference, gen);
            var notNull = gen.DefineLabel();

            gen.Emit(OpCodes.Brtrue_S, notNull);
            ifNull.Emit(member, gen);
            gen.MarkLabel(notNull);
            if (ifNotNull != null)             // yeah, I know that reads funny :)
            {
                ifNotNull.Emit(member, gen);
            }
        }
コード例 #10
0
        bool Emit(IILEmitter emitter, ref Local local, bool upper, bool invert, Instruction falseTarget)
        {
            var ic = upper ? _upper : _lower;

            if (!ic.HasValue)
            {
                return(false);
            }
            var c        = Base.Lang.Ints.Const(ic.Value.Value, Bytes, Signed);
            var compiler = new ExprCompiler(emitter);

            if (invert)
            {
                if (local == null)
                {
                    local = emitter.RequestTempLocal(c.Type);
                    emitter.Stloc(local);
                }

                compiler.Compile(c);
                emitter.Ldloc(local);
                var op = DnextFactory.CondBranch(upper, !ic.Value.Inclusive, Signed);
                emitter.Emit(op, falseTarget);
            }
            else
            {
                if (local != null)
                {
                    emitter.Ldloc(local);
                }
                compiler.Compile(c);
                var op = DnextFactory.CondBranch(!upper, !ic.Value.Inclusive, Signed);
                emitter.Emit(op, falseTarget);
            }

            return(true);
        }
コード例 #11
0
        /// <summary>
        /// Emits call to the method that contains de-mangler (injected as an <see cref="InjectedFeature"/>).
        /// This is to replace instruction(s) that load original constant in the IL
        /// </summary>
        /// <param name="emitter">IL emitter</param>
        /// <param name="rng">Pseudo-random number generator</param>
        /// <param name="instance">instance of the class where the method with injected de-mangler is located</param>
        /// <param name="mangled">mangled value</param>
        public void EmitCall(IILEmitter emitter, IRng rng, Local instance, object mangled)
        {
            var pi = Input is Var.Arg a ? a.Parameter : null;

            if (pi == null)
            {
                emitter.Ldloc(instance);
                Codec.LoadValue(emitter, mangled, true);
                Codec.EmitConversion(emitter, mangled.GetType(), Input.Type.ElementType.ToType());
                ((Var.Fld)Input).Stfld(emitter);
            }

            var method = Method.Method;

            emitter.Ldloc(instance);
            foreach (var pd in method.Parameters)
            {
                if (pd.IsNormalMethodParameter)
                {
                    if (pi == pd)
                    {
                        Codec.LoadValue(emitter, mangled, true);
                        Codec.EmitConversion(emitter, mangled.GetType(), pd.Type.ElementType.ToType());
                    }
                    else
                    {
                        Utils.RandomConst(emitter, pd.Type, rng);
                    }
                }
            }

            emitter.Callvirt(emitter.Importer.Import(method));
            if (method.HasReturnType)
            {
                if ((Output.Flags & VarFlags.Ret) == 0)
                {
                    emitter.Emit(OpCodes.Pop);
                }
            }

            if (Output is Var.Fld f)
            {
                emitter.Ldloc(instance);
                f.Ldfld(emitter);
            }
        }
コード例 #12
0
        public void EmitNew(IILEmitter emitter, IRng rng, Local instance)
        {
            var ctor = Flag.Type.Ctors.RandomElementOrDefault(rng);

            if (ctor == null || (Flag.Ctor != null && rng.NextBoolean()))
            {
                foreach (var pd in Flag.Ctor.Parameters)
                {
                    if (pd.IsNormalMethodParameter)
                    {
                        if (pd == Flag.FlagParameter)
                        {
                            EmitFlagValue(emitter, rng);
                        }
                        else
                        {
                            Utils.RandomConst(emitter, pd.Type, rng);
                        }
                    }
                }

                emitter.Newobj(emitter.Importer.Import(Flag.Ctor));
                emitter.Stloc(instance);
            }
            else
            {
                foreach (var pd in ctor.Parameters)
                {
                    if (pd.IsNormalMethodParameter)
                    {
                        Utils.RandomConst(emitter, pd.Type, rng);
                    }
                }

                emitter.Newobj(emitter.Importer.Import(ctor));
                emitter.Stloc(instance);
                emitter.Ldloc(instance);
                EmitFlagValue(emitter, rng);
                emitter.Emit(OpCodes.Stfld, emitter.Importer.Import(Flag.Field));
            }
        }
コード例 #13
0
        public void ConvertTo(IILEmitter emitter, ElementType to)
        {
            switch (to)
            {
            case ElementType.I1:
                emitter.Emit(OpCodes.Conv_I1);
                break;

            case ElementType.I2:
                emitter.Emit(OpCodes.Conv_I2);
                break;

            case ElementType.I4:
                emitter.Emit(OpCodes.Conv_I4);
                break;

            case ElementType.I8:
                emitter.Emit(OpCodes.Conv_I8);
                break;

            case ElementType.U1:
                emitter.Emit(OpCodes.Conv_U1);
                break;

            case ElementType.U2:
                emitter.Emit(OpCodes.Conv_U2);
                break;

            case ElementType.U4:
                emitter.Emit(OpCodes.Conv_U4);
                break;

            case ElementType.U8:
                emitter.Emit(OpCodes.Conv_U8);
                break;
            }
        }
コード例 #14
0
ファイル: Extensions.cs プロジェクト: dotnet-toolset/Netfuser
 public static IILEmitter Emit(this IILEmitter emitter, OpCode code, ITypeDefOrRef type) =>
 emitter.Emit(Instruction.Create(code, type));
コード例 #15
0
ファイル: Extensions.cs プロジェクト: dotnet-toolset/Netfuser
 public static IILEmitter Switch(this IILEmitter emitter, IList <Instruction> targets) =>
 emitter.Emit(Instruction.Create(OpCodes.Switch, targets));
コード例 #16
0
ファイル: Extensions.cs プロジェクト: dotnet-toolset/Netfuser
 public static IILEmitter Emit(this IILEmitter emitter, OpCode code, Instruction target) =>
 emitter.Emit(Instruction.Create(code, target));
コード例 #17
0
ファイル: Extensions.cs プロジェクト: dotnet-toolset/Netfuser
 public static IILEmitter Emit(this IILEmitter emitter, OpCode code, string v) =>
 emitter.Emit(Instruction.Create(code, v));
コード例 #18
0
ファイル: Extensions.cs プロジェクト: dotnet-toolset/Netfuser
 public static IILEmitter Emit(this IILEmitter emitter, OpCode code, Local l) =>
 emitter.Emit(Instruction.Create(code, l));
コード例 #19
0
ファイル: Extensions.cs プロジェクト: dotnet-toolset/Netfuser
 public static IILEmitter Emit(this IILEmitter emitter, OpCode code, Parameter p) =>
 emitter.Emit(Instruction.Create(code, p));
コード例 #20
0
ファイル: Extensions.cs プロジェクト: dotnet-toolset/Netfuser
 public static IILEmitter Emit(this IILEmitter emitter, OpCode code, MethodSig ms) =>
 emitter.Emit(Instruction.Create(code, ms));
コード例 #21
0
ファイル: Extensions.cs プロジェクト: dotnet-toolset/Netfuser
 public static IILEmitter Emit(this IILEmitter emitter, OpCode code, ITokenOperand to) =>
 emitter.Emit(Instruction.Create(code, to));
コード例 #22
0
ファイル: Extensions.cs プロジェクト: dotnet-toolset/Netfuser
 public static IILEmitter Emit(this IILEmitter emitter, OpCode code, IField f) =>
 emitter.Emit(Instruction.Create(code, f));
コード例 #23
0
        public static void RandomConst(IILEmitter il, TypeSig t, IRng rng)
        {
            switch (t.ElementType)
            {
            case ElementType.I1:
                il.Const(rng.NextInt8());
                break;

            case ElementType.I2:
                il.Const(rng.NextInt16());
                break;

            case ElementType.I4:
                il.Const(rng.NextInt32());
                break;

            case ElementType.I8:
                il.Const(rng.NextInt64());
                break;

            case ElementType.U1:
                il.Const(rng.NextUInt8());
                break;

            case ElementType.U2:
                il.Const(rng.NextUInt16());
                break;

            case ElementType.U4:
                il.Const(rng.NextUInt32());
                break;

            case ElementType.U8:
                il.Const(rng.NextUInt64());
                break;

            case ElementType.R4:
                il.Const(rng.NextFloat());
                break;

            case ElementType.R8:
                il.Const(rng.NextDouble());
                break;

            case ElementType.Char:
                il.Const((char)rng.NextUInt16());
                break;

            case ElementType.Boolean:
                il.Const(rng.NextBoolean());
                break;

            default:
                if (t.IsValueType)
                {
                    var it = il.Importer.Import(t);
                    using (il.UseTempLocal(it, out var l))
                    {
                        il.Ldloca(l);
                        il.Initobj(new TypeSpecUser(it));
                        il.Ldloc(l);
                    }
                }
                else
                {
                    il.Emit(OpCodes.Ldnull);
                }
                break;
            }
        }
コード例 #24
0
        private void EmitCastToType(Type typeFrom, Type typeTo)
        {
            if (!typeFrom.IsValueType && typeTo.IsValueType)
            {
                _ilg.Emit(OpCodes.Unbox_Any, _ilg.Importer.Import(typeTo));
                return;
            }

            if (typeFrom.IsValueType && !typeTo.IsValueType)
            {
                _ilg.Emit(OpCodes.Box, _ilg.Importer.Import(typeFrom));
                if (typeTo != typeof(object))
                {
                    _ilg.Emit(OpCodes.Castclass, _ilg.Importer.Import(typeTo));
                    return;
                }

                return;
            }

            if (!typeFrom.IsValueType && !typeTo.IsValueType)
            {
                _ilg.Emit(OpCodes.Castclass, _ilg.Importer.Import(typeTo));
                return;
            }

            throw new NotSupportedException($"{typeFrom} => {typeTo}");
        }
コード例 #25
0
 public override void Load(IILEmitter emitter)
 {
     emitter.Emit(OpCodes.Ldarg_0);
     Ldfld(emitter);
 }
コード例 #26
0
ファイル: Extensions.cs プロジェクト: dotnet-toolset/Netfuser
 public static IILEmitter Emit(this IILEmitter emitter, OpCode code, MemberRef mr) =>
 emitter.Emit(Instruction.Create(code, mr));
コード例 #27
0
 public void Ldfld(IILEmitter emitter)
 {
     emitter.Emit(Instruction.Create(OpCodes.Ldfld, _resolver?.Invoke(Field) ?? Field));
 }