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; } }
public void EmitDemangler(IILEmitter emitter) { new ExprCompiler(emitter) { ParameterResolver = ParameterResolver }.Compile(_decoder); }
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); } }
public static IILEmitter Emit(this IILEmitter emitter, IEnumerable <Instruction> instructions) { foreach (var i in instructions) { emitter.Emit(i.Clone()); } return(emitter); }
public static IILEmitter Emit(this IILEmitter emitter, params OpCode[] codes) { foreach (var code in codes) { emitter.Emit(Instruction.Create(code)); } return(emitter); }
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); } }
/// <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); }
public override void Store(IILEmitter emitter, Action pushValue = null) { pushValue?.Invoke(); if (Parameter.IsReturnTypeParameter) { emitter.Emit(OpCodes.Ret); } else { emitter.Starg(Parameter); } }
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); } }
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); } } }
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 } }
public override void Load(IILEmitter emitter) { if (Parameter.IsReturnTypeParameter) { throw new NotSupportedException(); } if (Parameter.ParamDef?.IsOut ?? false) { emitter.Ldarga(Parameter); } else { emitter.Ldarg(Parameter); } }
/// <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); } }
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); } }
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)); } }
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; } }
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); }
public IfNullExpression(Reference reference, IILEmitter ifNull, IILEmitter ifNotNull = null) { this.reference = reference; this.ifNull = ifNull; this.ifNotNull = ifNotNull; }
public IfNullExpression(Reference reference, IILEmitter ifNull, IILEmitter ifNotNull = null) { this.reference = reference ?? throw new ArgumentNullException(nameof(reference)); this.ifNull = ifNull; this.ifNotNull = ifNotNull; }
public IfNullExpression(Expression expression, IILEmitter ifNull, IILEmitter ifNotNull = null) { this.expression = expression ?? throw new ArgumentNullException(nameof(expression)); this.ifNull = ifNull; this.ifNotNull = ifNotNull; }
public static IILEmitter Emit(this IILEmitter emitter, OpCode code, string v) => emitter.Emit(Instruction.Create(code, v));
public IfNullExpression(Reference reference, IILEmitter ifNull, IILEmitter ifNotNull = null) { this.reference = reference; this.ifNull = ifNull; this.ifNotNull = ifNotNull; }
/// <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); }
public void EmitConversion(IILEmitter emitter, Type fromType, Type toType) { emitter.NumericConversion(fromType, toType, false); }
public static IILEmitter Emit(this IILEmitter emitter, OpCode code, Instruction target) => emitter.Emit(Instruction.Create(code, target));
public void LoadValue(IILEmitter emitter, object value, bool mangled) { emitter.Const(value, value.GetType()); }
public static IILEmitter Switch(this IILEmitter emitter, IList <Instruction> targets) => emitter.Emit(Instruction.Create(OpCodes.Switch, targets));