static FutureExtensions() { try { var prepForRemotingMethod = typeof(Exception).GetMethod("PrepForRemoting", BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null); if (prepForRemotingMethod == null) { _prepareForRemoting = e => e; Trace.TraceWarning("Couldn't get internal method for preserving stack traces. Stack traces may not contain all necessary information."); } else { var dm = new DynamicMethod("Exception_PrepForRemotingWrapper", typeof(Exception), new[] { typeof(Exception) }, true); var g = new MethodGenerator(new MsilWriter(dm)); g.Load(g.GetParameter(0)); g.Call(prepForRemotingMethod); if (prepForRemotingMethod.ReturnType != typeof(Exception)) { g.Load(g.GetParameter(0)); } g.Return(); _prepareForRemoting = (Func <Exception, Exception>)dm.CreateDelegate(typeof(Func <Exception, Exception>)); } } catch (Exception ex) { _prepareForRemoting = e => e; Trace.TraceWarning("Couldn't construct method for preserving stack traces. Stack traces may not contain all necessary information. - " + ex); } }
public void Foreach() { DynamicMethod method = new DynamicMethod("temp", typeof(int), new Type[] { typeof(List <int>) }); MethodGenerator g = new MethodGenerator(method); List <int> list = new List <int> { 1, 2, 3, 4, 5 }; g.LoadParameter(0); var count = g.Declare <int>(); g.ForEach(item => { g.Load(item); g.Store(count); }); g.Load(count); g.Return(); var result = (int)method.Invoke(null, new object[] { list }); Assert.AreEqual(5, result); }
public void If_Condition_And() { DynamicMethod method = new DynamicMethod("temp", typeof(int), Type.EmptyTypes); MethodGenerator g = new MethodGenerator(method); var a = g.Declare(5); g.If(() => {//a<10 && a>6 g.And(() => { g.Load(a); g.Load(10); return(LogicOperator.LessThan); }, () => { g.Load(a); g.Load(6); return(LogicOperator.GreaterThan); }); return(LogicOperator.IsTrue); }, () => { g.Increment(a); }); g.Load(a); g.Return(); int result = (int)method.Invoke(null, new object[] { }); Assert.AreEqual(5, result); }
public void If_Else() { DynamicMethod method = new DynamicMethod("temp", typeof(int), Type.EmptyTypes); MethodGenerator g = new MethodGenerator(method); var count = g.Declare <int>(); g.If(() => { g.Load(true); return(LogicOperator.IsTrue); }, () => { g.Assign(count, () => { g.Load(1); }); }, () => { g.Assign(count, () => { g.Load(2); }); }); g.Load(count); g.Return(); int result = (int)method.Invoke(null, null); Assert.AreEqual(1, result); }
public override void GenerateDeserializeIL(MethodGenerator g) { SetMember(g, () => { var count = g.Declare <int>(); g.Assign(count, () => { SerializationMethodHelper.ReadLength(g, this.DTOMemberName);//读取数量 }); var list = g.Declare(this.TargetType); g.If(() => { g.Load(count); g.Load(0); return(LogicOperator.LessThan); }, () => { //数量小于1 //list = new List<T>(); var elementType = this.TargetType.ResolveElementType(); g.Assign(list, () => { g.NewObject(this.TargetType); }); }, () => { //list = new List<T>(); g.Assign(list, () => { g.NewObject(this.TargetType); }); var elementType = this.TargetType.ResolveElementType(); g.For(count, (index) => { var item = g.Declare(elementType); g.Assign(item, () => { SerializationMethodHelper.ReadElement(g, this.DTOMemberName, elementType, index); }); g.Load(list); g.Load(item); g.Call(this.TargetType.ResolveMethod("Add", elementType)); }); }); g.Load(list); }); }
public void GenerateFill(ICilWriter msilWriter) { var g = new MethodGenerator(msilWriter); var instance = g.GetParameter(0); g.If(() => { g.Load(instance); return(BinaryOperator.IsNull); }); { if (_def.Type.IsAbstract) { g.BeginCall(typeof(BarfErrors).ResolveMethod("RaiseAbstractConstructionError", typeof(Type))); g.Load(_def.Type); g.EndCall(); } else { g.BeginAssign(instance); { g.NewObject(_def.Type); } g.EndAssign(); } } g.EndIf(); foreach (var part in _def.Parts) { g.BeginScope(); { var member = g.CreateExpression(instance); if (part.Member == null) { member.MakeReadOnly(); } else { member.AddMember(part.Member); } var context = new GenFillContext(g, member, part); var builder = PartResolver.Current.GetPartBuilder(part.Type, part, true); builder.GenerateFillPart(context); } g.EndScope(); } g.Return(); }
public void GreaterThanOrEqualTo_False() { DynamicMethod method = new DynamicMethod("temp", typeof(int), Type.EmptyTypes); MethodGenerator g = new MethodGenerator(method); g.Load(2); g.Load(3); g.Compare(LogicOperator.GreaterThanOrEqualTo); g.Return(); int result = (int)method.Invoke(null, new object[] { }); Assert.AreEqual(0, result); }
public void NotEqual_True() { DynamicMethod method = new DynamicMethod("temp", typeof(int), Type.EmptyTypes); MethodGenerator g = new MethodGenerator(method); g.Load(2); g.Load(3); g.Compare(LogicOperator.AreNotEqual); g.Return(); int result = (int)method.Invoke(null, new object[] { }); Assert.AreEqual(1, result); }
public override void GenerateSerializeIL(MethodGenerator g) { g.If(() => { LoadMemberValue(g);//加载集合到堆栈上,检查是否为null return(LogicOperator.IsNull); }, () => { SerializationMethodHelper.WriteArray(g, this.DTOMemberName); }, () => { var elementType = this.TargetType.ResolveElementType(); ////写入数组 SerializationMethodHelper.WriteArray(g, this.DTOMemberName); //写入每个项 LoadMemberValue(g); g.ForEach(item => { SerializationMethodHelper.WriteElement(g, this.DTOMemberName, elementType, () => { g.Load(item); }); }); }); }
public static void WriteElement(MethodGenerator g, string dtoMemberName, Type elementType, Action loadValue) { var method = typeof(IDTOWriter).ResolveMethod("WriteElement", new Type[] { elementType }, MethodParameter.Create <string>(), MethodParameter.Create <bool>(), MethodParameter.CreateGeneric(elementType)); var prmIndex = SerializationArgs.WriterIndex; g.Call(method, () => { g.LoadParameter(prmIndex); g.Load(dtoMemberName); g.Load(IsPrimitive(elementType)); loadValue(); }); }
public void GenerateAssertAreEqual(ICilWriter msilWriter) { var g = new MethodGenerator(msilWriter); var expected = g.GetParameter(0); var actual = g.GetParameter(1); var assertAreEqual = typeof(Assert).ResolveMethod("AreEqual", typeof(object), typeof(object)); var assertAreNotEqual = typeof(Assert).ResolveMethod("AreNotEqual", typeof(object), typeof(object)); if (_def.Type.IsValueType) { GenerateAssertPartsAreEqual(g); } else { g.If(() => { g.Load(expected); return(BinaryOperator.IsNull); }); { g.BeginCall(assertAreEqual); { g.LoadNull(); g.Load(actual); } g.EndCall(); } g.Else(); { g.BeginCall(assertAreNotEqual); { g.LoadNull(); g.Load(actual); } g.EndCall(); GenerateAssertPartsAreEqual(g); } g.EndIf(); } g.Return(); }
public void For() { DynamicMethod method = new DynamicMethod("temp", typeof(int), new Type[] { typeof(List <int>) }); MethodGenerator g = new MethodGenerator(method); IVariable array = g.Declare <List <int> >(); g.Assign(array, () => { g.LoadParameter(0); }); var count = g.Declare <int>(); var number = g.Declare(0); g.Assign(count, () => { g.LoadParameter(0); g.LoadMember("Count"); }); g.For(count, (index) => { g.Assign(number, () => { g.LoadParameter(0); g.Load(index); g.Call(typeof(List <int>).ResolveMethod("get_Item", typeof(int))); g.Load(number); g.Add <int>(); }); }); g.Load(number); g.Return(); List <int> list = new List <int> { 1, 2, 3, 4, 5 }; var result = (int)method.Invoke(null, new object[] { list }); Assert.AreEqual(15, result); }
/// <summary> /// 读取数组的长度 /// </summary> /// <param name="g"></param> /// <param name="dtoMemberName"></param> /// <param name="valueType"></param> public static void ReadLength(MethodGenerator g, string dtoMemberName) { var method = typeof(IDTOReader).ResolveMethod("ReadLength", _readArgs); var prmIndex = SerializationArgs.ReaderIndex; g.Call(method, () => { g.LoadParameter(prmIndex); g.Load(dtoMemberName); }); }
public static void WriteArray(MethodGenerator g, string dtoMemberName) { var method = typeof(IDTOWriter).ResolveMethod("WriteArray", new Type[] { typeof(string) }); var prmIndex = SerializationArgs.WriterIndex; g.Call(method, () => { g.LoadParameter(prmIndex); g.Load(dtoMemberName); }); }
public void IntToObject() { DynamicMethod method = new DynamicMethod("temp", typeof(object), Type.EmptyTypes); MethodGenerator g = new MethodGenerator(method); g.Load(1); g.Cast(typeof(object)); g.Return(); object result = (object)method.Invoke(null, new object[] { }); Assert.AreEqual(1, result); }
public void DeclareInt() { DynamicMethod method = new DynamicMethod("temp", typeof(int), Type.EmptyTypes); MethodGenerator g = new MethodGenerator(method); IVariable count = g.Declare(3); g.Load(count); g.Return(); int result = (int)method.Invoke(null, new object[] {}); Assert.AreEqual(3, result); }
public void DeclareString() { DynamicMethod method = new DynamicMethod("temp", typeof(string), Type.EmptyTypes); MethodGenerator g = new MethodGenerator(method); IVariable count = g.Declare("哈哈哈哈哈"); g.Load(count); g.Return(); string result = (string)method.Invoke(null, new object[] { }); Assert.AreEqual("哈哈哈哈哈", result); }
public static void ReadElement(MethodGenerator g, string dtoMemberName, Type elementType, IVariable index) { var method = typeof(IDTOReader).ResolveMethod("ReadElement", new Type[] { elementType }, MethodParameter.Create <string>(), MethodParameter.Create <int>()); var prmIndex = SerializationArgs.ReaderIndex; g.Call(method, () => { g.LoadParameter(prmIndex); g.Load(dtoMemberName); g.LoadVariable(index, LoadOptions.Default); }); }
public static void WriteBlob(MethodGenerator g, string dtoMemberName, Action loadValue) { var method = typeof(IDTOWriter).ResolveMethod("WriteBlob", new Type[] { typeof(string), typeof(byte[]) }); var prmIndex = SerializationArgs.WriterIndex; g.Call(method, () => { g.LoadParameter(prmIndex); g.Load(dtoMemberName); loadValue(); }); }
public void While() { DynamicMethod method = new DynamicMethod("temp", typeof(int), Type.EmptyTypes); MethodGenerator g = new MethodGenerator(method); const int maxNumber = 15; var num = g.Declare(0); var max = g.Declare(maxNumber); g.While(() => { g.Load(num); g.Load(max); return(LogicOperator.LessThan); }, () => { g.Increment(num); }); g.Load(num); g.Return(); int result = (int)method.Invoke(null, new object[] { }); Assert.AreEqual(maxNumber, result); }
private void Increment(Symbol symbol) { EmitLoadSymbol(symbol, SymbolLoadMode.Raw); bool byRef = symbol.Type.IsByRef; if (byRef) { MethodGenerator.Dup(); MethodGenerator.Load(IrisType.Integer); } MethodGenerator.PushIntConst(1); MethodGenerator.Operator(Operator.Add); if (byRef) { MethodGenerator.Store(IrisType.Integer); } else { EmitStoreSymbol(symbol); } }
/// <summary> /// <para>得到读取某个类型的IL代码</para> /// <para>reader.ReadXXX(); 或 deserialzer.Deserialze();</para> /// </summary> /// <param name="g"></param> /// <param name="valueType"></param> /// <param name="loadValue"></param> public static void Read(MethodGenerator g, string dtoMemberName, Type valueType) { var method = SerializationMethodHelper.GetTypeMethod(valueType, SerializationMethodType.Deserialize); var prmIndex = SerializationMethodHelper.GetParameterIndex(method, SerializationMethodType.Deserialize); g.Call(method, () => { g.LoadParameter(prmIndex); g.Load(dtoMemberName); //if (prmIndex == SerializationArgs.DeserializerIndex) //{ // //是deserializer.Deserializ(); // g.LoadVariable(SerializationArgs.TypeNameTable); //} }); }
private static void GenerateConvert( MethodGenerator g, MethodInfo converter, IExpression source, IExpression dest) { g.BeginAssign(dest); { g.BeginCall(converter); { g.Load(source); } g.EndCall(); } g.EndAssign(); }
public void CallStatic() { DynamicMethod method = new DynamicMethod("temp", typeof(int), new Type[] { typeof(SampleCls) }); MethodGenerator g = new MethodGenerator(method); g.Call(typeof(SampleCls).ResolveMethod("IncreaseStatic", typeof(int)), () => { g.Load(5); }); g.Return(); int result = (int)method.Invoke(null, new object[] { new SampleCls() }); Assert.AreEqual(5, result); }
private static CreateInstanceMethod GenerateCreateInstanceMethod(ConstructorInfo constructor) { var objectType = constructor.DeclaringType; DynamicMethod method = new DynamicMethod(string.Format("CreateInstanceByConstructor_{0}", Guid.NewGuid().ToString("n")) , typeof(object) , new Type[] { typeof(object[]) } , true); MethodGenerator g = new MethodGenerator(method); //以下代码把数组参数转成,new T(arg0,arg1)的形式 var result = g.Declare(objectType, "result"); var objs = g.Declare <object[]>(); g.Assign(objs, () => { g.LoadParameter(0); }); g.Assign(result, () => { g.NewObject(constructor, () => { var index = g.Declare <int>(); var prms = constructor.GetParameters(); for (var i = 0; i < prms.Length; i++) { g.Assign(index, () => { g.Load(i); }); g.LoadElement(objs, index); g.Cast(prms[i].ParameterType); } }); }); g.LoadVariable("result"); g.Cast(typeof(object)); g.Return(); var invoke = method.CreateDelegate(typeof(Func <object[], object>)); return(new CreateInstanceMethod(invoke)); }
/// <summary> /// <para>得到写入某个类型的IL代码</para> /// <para>writer.Write(value); 或 serialzer.Serialze(value);</para> /// </summary> /// <param name="g"></param> /// <param name="valueType"></param> /// <param name="loadValue"></param> public static void Write(MethodGenerator g, string dtoMemberName, Type valueType, Action <Type> loadValue) { var method = SerializationMethodHelper.GetTypeMethod(valueType, SerializationMethodType.Serialize); var prmIndex = SerializationMethodHelper.GetParameterIndex(method, SerializationMethodType.Serialize); g.Call(method, () => { g.LoadParameter(prmIndex); g.Load(dtoMemberName); var argType = method.GetParameters()[1].ParameterType; loadValue(argType); //if (prmIndex == SerializationArgs.SerializerIndex) //{ // //是serializer.Serializ(); // g.LoadVariable(SerializationArgs.TypeNameTable); //} }); }
public void GenerateInnerDeserializeMethod(ICilWriter msilWriter) { var g = new MethodGenerator(msilWriter); var instance = g.CreateExpression(g.GetParameter(0)); var args = g.CreateExpression(g.GetParameter(1)); var header = g.DeclareLocal(typeof(BarfObjectHeader)); g.BeginAssign(header); { g.Load(args); g.Call(typeof(BarfDeserializationArgs) .ResolveMethod("BeginObject") .MakeGenericMethod(_def.Type)); } g.EndAssign(); var version = g.CreateExpression(header).AddMember("Version"); g.If(() => { g.Load(header); g.LoadMember("IsNull"); return(BinaryOperator.IsTrue); }); { g.BeginAssign(instance); g.LoadNull(); g.EndAssign(); } g.Else(); { g.If(() => { g.Load(instance); return(BinaryOperator.IsNull); }); { if (_def.Type.IsAbstract) { g.BeginCall(typeof(BarfErrors).ResolveMethod("RaiseAbstractConstructionError", typeof(Type))); g.Load(_def.Type); g.EndCall(); } else { g.BeginAssign(instance); g.NewObject(instance.Type); g.EndAssign(); } } g.EndIf(); var partsByVersion = _def.Parts .GroupBy <PartDefinition, int>(part => part.Version) .OrderBy <IGrouping <int, PartDefinition>, int>(group => group.Key); int count = 0; foreach (var versionGroup in partsByVersion) { g.If(() => { g.Load(version); g.Load(versionGroup.Key); return(BinaryOperator.GreaterThanOrEqualTo); }); { foreach (var part in versionGroup) { Trace.WriteLine("\tBuilding Deserialize Part - " + part.FullName); g.BeginScope(); var context = new GenDeserializeContext(g, part, instance, args, header); part.GetCurrentBuilder() .GenerateDeserializePart(context); g.EndScope(); } } count++; } for (; count > 0; --count) { g.EndIf(); } if (_def.IsForwardCompatible) { g.If(() => { g.Load(header).LoadMember("Version"); g.Load(_def.CurrentVersion); return(BinaryOperator.GreaterThan); }); { g.Load(args); g.BeginCall(typeof(BarfDeserializationArgs) .ResolveMethod( "CaptureFutureData", new[] { _def.Type }, typeof(BarfObjectHeader), new GenericParameter(0).MakeByRefType())); { g.Load(header); g.Load(instance, LoadOptions.AnyAsAddress); } g.EndCall(); } g.EndIf(); } } g.EndIf(); g.Load(args).BeginCall(typeof(BarfDeserializationArgs) .ResolveMethod("EndObject", new[] { _def.Type }, typeof(BarfObjectHeader))); { g.Load(header); } g.EndCall(); g.Return(); }
/// <summary> /// Generates the body of the serialize method. /// </summary> /// <param name="msilWriter">The MSIL writer to write to.</param> public void GenerateSerializeMethod(ICilWriter msilWriter) { var g = new MethodGenerator(msilWriter); var instance = g.GetParameter(0); var args = g.GetParameter(1); if (!_def.Type.IsValueType) { g.If(() => { g.Load(instance); return(BinaryOperator.IsNull); }); { g.Load(args); // todo - call through MemberResolver g.Call(typeof(BarfSerializationArgs).GetMethod("WriteNullObject")); g.Return(); } g.EndIf(); } IVariable typeContext; MethodInfo beginMethod; MethodInfo endMethod; if (_def.IsForwardCompatible) { typeContext = g.DeclareLocal(typeof(BarfSerializationArgs.TypeContext)); beginMethod = typeof(BarfSerializationArgs).GetMethods(BindingFlags.Instance | BindingFlags.Public) .Where <MethodInfo>(m => m.Name == "BeginObject") .Where <MethodInfo>(m => { var ps = m.GetParameters(); return(ps.Length == 1 && ps[0].ParameterType.IsGenericParameter); }) .FirstOrDefault <MethodInfo>() .MakeGenericMethod(_def.Type); endMethod = typeof(BarfSerializationArgs).ResolveMethod("EndObject", typeof(BarfSerializationArgs.TypeContext)); } else { typeContext = g.DeclareLocal(typeof(long)); beginMethod = typeof(BarfSerializationArgs) .ResolveMethod("BeginObject", Type.EmptyTypes) .MakeGenericMethod(_def.Type); endMethod = typeof(BarfSerializationArgs).ResolveMethod("EndObject", typeof(long)); } g.Load(args); g.BeginCall(beginMethod); if (_def.IsForwardCompatible) { g.Load(instance); } g.EndCall(); g.Store(typeContext); foreach (var part in _def.Parts) { Trace.WriteLine("\tBuilding Serialize Part - " + part.FullName); g.BeginScope(); { var context = new GenSerializeContext(g, part, g.CreateExpression(instance)); part.GetCurrentBuilder() .GenerateSerializePart(context); } g.EndScope(); } g.Load(args); g.BeginCall(endMethod); { g.Load(typeContext); } g.EndCall(); g.Return(); }
public override void GenerateDeserializeIL(MethodGenerator g) { SetMember(g, () => { var array = g.Declare(this.TargetType); if (this.MemberAttribute.IsBlob) { g.Assign(array, () => { SerializationMethodHelper.ReadBlob(g, this.DTOMemberName);//读取数量 }); } else { var length = g.Declare <int>(); g.Assign(length, () => { SerializationMethodHelper.ReadLength(g, this.DTOMemberName);//读取数量 }); g.If(() => { g.Load(length); g.Load(0); return(LogicOperator.LessThan); }, () => { //数量小于1 //array = new array[]; var elementType = this.TargetType.ResolveElementType(); g.Assign(array, () => { g.NewArray(elementType, () => { g.Load(length); }); }); }, () => { var elementType = this.TargetType.ResolveElementType(); //int[] = new int[c]; g.Assign(array, () => { g.NewArray(elementType, () => { g.Load(length); }); }); g.For(length, (index) => { var item = g.Declare(elementType); g.Assign(item, () => { SerializationMethodHelper.ReadElement(g, this.DTOMemberName, elementType, index); }); g.StoreElement(array, index, item); }); }); } g.Load(array); }); }