/// <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);
            }
        }
Beispiel #2
0
 private void EmitNonNullableToNullableConversion(Type typeFrom, Type typeTo, bool isChecked)
 {
     using (_ilg.UseTempLocal(typeFrom, out var local))
     {
         var nonNullableType = typeTo.GetNonNullableType();
         EmitConvertToType(typeFrom, nonNullableType, isChecked);
         var constructor = typeTo.GetConstructor(new[] { nonNullableType });
         _ilg.Newobj(constructor);
         _ilg.Stloc(local);
         _ilg.Ldloc(local);
     }
 }
Beispiel #3
0
 public static void NewStringBuilder(IILEmitter emitter, Local initString = null)
 {
     if (initString != null)
     {
         emitter.Ldloc(initString);
         emitter.Newobj(Ctor_StringBuilder_String);
     }
     else
     {
         emitter.Newobj(Ctor_StringBuilder);
     }
 }
Beispiel #4
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);
                }
            }
        }
Beispiel #5
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);
        }
Beispiel #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);
            }
        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));
            }
        }
Beispiel #8
0
            public override void Store(IILEmitter emitter, Action pushValue = null)
            {
                if (pushValue == null)
                {
                    using (emitter.UseTempLocal(Array.Type.Next, out var local))
                    {
                        emitter.Stloc(local);
                        Array.Load(emitter);
                        emitter.Const(Index);
                        emitter.Ldloc(local);
                    }
                }
                else
                {
                    Array.Load(emitter);
                    emitter.Const(Index);
                    pushValue.Invoke();
                }

                emitter.Stelem(Array.Type.Next);
            }
Beispiel #9
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;
            }
        }
Beispiel #10
0
 public override void Load(IILEmitter emitter)
 {
     emitter.Ldloc(Local);
 }