示例#1
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;
            }
        }
示例#2
0
 public void EmitDemangler(IILEmitter emitter)
 {
     new ExprCompiler(emitter)
     {
         ParameterResolver = ParameterResolver
     }.Compile(_decoder);
 }
示例#3
0
 public virtual void EmitConversion(IILEmitter emitter, Type fromType, Type toType)
 {
     if (fromType != toType)
     {
         throw new NotSupportedException();
     }
 }
        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);
            }
        }
示例#5
0
 public static IILEmitter Emit(this IILEmitter emitter, IEnumerable <Instruction> instructions)
 {
     foreach (var i in instructions)
     {
         emitter.Emit(i.Clone());
     }
     return(emitter);
 }
示例#6
0
 public static IILEmitter Emit(this IILEmitter emitter, params OpCode[] codes)
 {
     foreach (var code in codes)
     {
         emitter.Emit(Instruction.Create(code));
     }
     return(emitter);
 }
示例#7
0
        public void EmitDemangler(IILEmitter emitter)
        {
            if (!Context.MappedTypes.TryGetValue(Demangler.Method.DeclaringType.CreateKey(), out _))
            {
                Context.Error("demangler must be defined in the target assembly");
            }
            var method = emitter.Importer.Import(Demangler.Method);
            var mi     = emitter.Importer.Import(method);

            emitter.Call(mi);
        }
 private void EmitFlagValue(IILEmitter emitter, IRng rng)
 {
     if (Constraints != null)
     {
         Constraints.EmitValue(emitter, rng);
     }
     else
     {
         var(signed, bytes) = IntConstraints.GetProps(Flag.Field.FieldType.ElementType);
         emitter.Const(Value.Value, bytes, signed);
     }
 }
示例#9
0
 /// <summary>
 /// Get the instance of <see cref="IILEmitter"/> for the body of the target method.
 /// <see cref="IILEmitter"/> should have all you need to inject code into the target method's body
 /// </summary>
 /// <param name="create">the default is <see langword="true"/>, meaning that new emitter will be created if there's none yet,
 /// set to <see langword="false"/> if you don't want to create new one if none exists, in this case <see langword="null"/> may be returned</param>
 /// <returns>instance of <see cref="IILEmitter"/></returns>
 public IILEmitter GetEmitter(bool create = true)
 {
     if (_emitter == null && create)
     {
         lock (this)
             if (_emitter == null)
             {
                 _emitter = DnextFactory.NewILEmitter(Context.TargetModule, Importer, Fragment);
             }
     }
     return(_emitter);
 }
示例#10
0
 public override void Store(IILEmitter emitter, Action pushValue = null)
 {
     pushValue?.Invoke();
     if (Parameter.IsReturnTypeParameter)
     {
         emitter.Emit(OpCodes.Ret);
     }
     else
     {
         emitter.Starg(Parameter);
     }
 }
示例#11
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);
     }
 }
示例#12
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);
                }
            }
        }
示例#13
0
 public StringMangleContext(IStringMangler mangler, MethodDef sourceMethod, IILEmitter emitter, IEnumerable <StringPiece> parts)
 {
     Mangler      = mangler;
     SourceMethod = sourceMethod;
     Emitter      = emitter;
     Pieces       = new Queue <StringPiece>(parts);
     if (Pieces.Count == 0)
     {
         throw new CodeBug.Unreachable();
     }
     if (Pieces.Count > 1 && Mangler.Rng.NextBoolean())
     {
         EnsureStringBuilderOnStackTop(); // if there are multiple parts, we sometimes initialize StringBuilder, and sometimes leave it to the point when the second part is about to be demangled
     }
 }
示例#14
0
 public override void Load(IILEmitter emitter)
 {
     if (Parameter.IsReturnTypeParameter)
     {
         throw new NotSupportedException();
     }
     if (Parameter.ParamDef?.IsOut ?? false)
     {
         emitter.Ldarga(Parameter);
     }
     else
     {
         emitter.Ldarg(Parameter);
     }
 }
示例#15
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);
            }
        }
示例#16
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);
            }
        }
示例#17
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);
            }
示例#18
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));
            }
        }
示例#19
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);
            }
        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;
            }
        }
示例#21
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);
        }
示例#22
0
 public IfNullExpression(Reference reference, IILEmitter ifNull, IILEmitter ifNotNull = null)
 {
     this.reference = reference;
     this.ifNull    = ifNull;
     this.ifNotNull = ifNotNull;
 }
示例#23
0
 public IfNullExpression(Reference reference, IILEmitter ifNull, IILEmitter ifNotNull = null)
 {
     this.reference = reference ?? throw new ArgumentNullException(nameof(reference));
     this.ifNull    = ifNull;
     this.ifNotNull = ifNotNull;
 }
示例#24
0
 public IfNullExpression(Expression expression, IILEmitter ifNull, IILEmitter ifNotNull = null)
 {
     this.expression = expression ?? throw new ArgumentNullException(nameof(expression));
     this.ifNull     = ifNull;
     this.ifNotNull  = ifNotNull;
 }
示例#25
0
 public static IILEmitter Emit(this IILEmitter emitter, OpCode code, string v) =>
 emitter.Emit(Instruction.Create(code, v));
示例#26
0
		public IfNullExpression(Reference reference, IILEmitter ifNull, IILEmitter ifNotNull = null)
		{
			this.reference = reference;
			this.ifNull = ifNull;
			this.ifNotNull = ifNotNull;
		}
示例#27
0
 /// <summary>
 /// Loads mangled constant, emits de-mangling code and stores it in the output variable
 /// </summary>
 /// <param name="target"></param>
 /// <param name="emitter">IL emitter</param>
 /// <param name="rng">Pseudo-random number generator</param>
 public override void Emit(MethodDef target, IILEmitter emitter, IRng rng)
 {
     Input.Load(emitter);
     Codec.EmitDemangler(emitter);
     Output.Store(emitter);
 }
示例#28
0
 public void EmitConversion(IILEmitter emitter, Type fromType, Type toType)
 {
     emitter.NumericConversion(fromType, toType, false);
 }
示例#29
0
 public static IILEmitter Emit(this IILEmitter emitter, OpCode code, Instruction target) =>
 emitter.Emit(Instruction.Create(code, target));
示例#30
0
 public void LoadValue(IILEmitter emitter, object value, bool mangled)
 {
     emitter.Const(value, value.GetType());
 }
示例#31
0
 public static IILEmitter Switch(this IILEmitter emitter, IList <Instruction> targets) =>
 emitter.Emit(Instruction.Create(OpCodes.Switch, targets));