/// <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); } }
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); } }
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); } } }
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 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 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; } }
public override void Load(IILEmitter emitter) { emitter.Ldloc(Local); }