/// <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 Expr(ICFMangleContext ctx) : base(ctx) { _invCompiled = new CilFragment(); _stateVar = new Local(ctx.Method.Module.CorLibTypes.Int32); var body = ctx.Method.Body; body.Variables.Add(_stateVar); body.InitLocals = true; var nm = new IntGenerator(ctx.Mangler.Rng, ctx.Mangler.Options.MaxMangleIterations); var codec = nm.Generate(); codec.ParameterResolver = p => p == nm.Argument ? _stateVar : null; _codec = codec; var emitter = DnextFactory.NewILEmitter(ctx.Method.Module, ctx.Importer, _invCompiled); codec.EmitDemangler(emitter); }
MethodDef CreateFlagCtor(FlagDef flag, Func <MethodSig, bool> validator) { MethodSig sig; var cats = new List <Tuple <FieldDef, TypeSig> >(); var it = flag.Type; var sm = it.TypeMapping.Source.Module; do { var qarg = Rng.NextInt32(1, 5); cats.Add(Tuple.Create(flag.Field, flag.Field.FieldType)); var fq = new Queue <FieldDef>( it.TypeMapping.Source.Fields.Where(f => !f.IsStatic & !f.IsLiteral & !f.HasFieldRVA)); while (cats.Count < qarg) { if (fq.Count > 0) { var f = fq.Dequeue(); cats.Add(Tuple.Create(f, f.FieldType)); } else { cats.Add(Tuple.Create <FieldDef, TypeSig>(null, sm.CorLibTypes.Int32)); } } cats.Shuffle(Rng); var args = cats.Select(c => c.Item2).ToArray(); sig = MethodSig.CreateInstance(sm.CorLibTypes.Void, args); } while (!validator(sig)); var ctor = new MethodDefUser(".ctor", sig, MethodImplAttributes.IL | MethodImplAttributes.Managed, MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.Public) { Body = new CilBody { MaxStack = 8 } }; var i = 0; foreach (var t in cats) { ctor.ParamDefs.Add(new ParamDefUser("a" + (i++), (ushort)i)); } var sc = new SigComparer(); IMethod baseCtor; var bc = it.Base?.Ctors.RandomElementOrDefault(Rng); var emitter = DnextFactory.NewILEmitter(sm); emitter.Emit(OpCodes.Ldarg_0); if (bc != null) { foreach (var pd in bc.Parameters) { if (pd.IsNormalMethodParameter) { var f = ctor.Parameters.FirstOrDefault(p => p.IsNormalMethodParameter && sc.Equals(p.Type, pd.Type)); if (f != null && Rng.NextBoolean()) { emitter.Ldarg(f); } else { Utils.RandomConst(emitter, pd.Type, Rng); } } } baseCtor = bc; } else { baseCtor = new MemberRefUser(sm, ".ctor", MethodSig.CreateInstance(sm.CorLibTypes.Void), sm.CorLibTypes.Object.TypeRef); } emitter.Call(baseCtor); Parameter flagpar = null; foreach (var p in ctor.Parameters) { if (p.IsNormalMethodParameter) { var t = cats[p.Index - 1]; if (t.Item1 != null) { emitter.Emit(OpCodes.Ldarg_0); emitter.Ldarg(p); emitter.Emit(Instruction.Create(OpCodes.Stfld, t.Item1)); if (t.Item1 == flag.Field) { flagpar = p; } } } } emitter.Emit(OpCodes.Ret); emitter.Replace(ctor.Body); flag.SetCtor(ctor, flagpar); return(ctor); }