public void EmitDeserialize(Emit emiter, Local value) { var ok = emiter.DefineLabel(nameof(VersionSerializer) + "OK" + Guid.NewGuid()); using (var array = emiter.DeclareLocal <ushort[]>("array")) { _arraySerializer.EmitDeserialize(emiter, array); // if(array.Length != 4) throw new Exception("Invalid count for version") emiter.LoadLocal(array); emiter.Call(typeof(Array).GetProperty(nameof(Array.Length)).GetMethod); emiter.LoadConstant(4); emiter.BranchIfEqual(ok); emiter.LoadConstant("Invalid count for version"); emiter.NewObject(typeof(Exception).GetConstructor(new[] { typeof(string) })); emiter.Throw(); emiter.MarkLabel(ok); // value = new Version(array[0], array[1], array[2], array[3]) for (var i = 0; i < 4; i++) { emiter.LoadLocal(array); emiter.LoadConstant(i); emiter.LoadElement <ushort>(); } emiter.NewObject(typeof(Version).GetConstructor(new[] { typeof(int), typeof(int), typeof(int), typeof(int) })); emiter.StoreLocal(value); } }
public void EmitSerialize(Emit emiter, Local value) { using (var address = emiter.DeclareLocal <string>("str")) using (var port = emiter.DeclareLocal <ushort>("port")) { var isNull = emiter.DefineLabel(); var write = emiter.DefineLabel(); // if (value == null) goto isNull emiter.LoadLocal(value); emiter.LoadNull(); emiter.BranchIfEqual(isNull); // address = value.Address.ToString() emiter.LoadLocal(value); emiter.Call(typeof(IPEndPoint).GetProperty(nameof(IPEndPoint.Address)).GetMethod); emiter.CallVirtual(typeof(IPAddress).GetMethod(nameof(IPAddress.ToString))); emiter.StoreLocal(address); // port = (ushort)value.Port emiter.LoadLocal(value); emiter.Call(typeof(IPEndPoint).GetProperty(nameof(IPEndPoint.Port)).GetMethod); emiter.Convert <ushort>(); emiter.StoreLocal(port); emiter.Branch(write); emiter.MarkLabel(isNull); // address = "255.255.255.255" emiter.LoadConstant("255.255.255.255"); emiter.StoreLocal(address); emiter.MarkLabel(write); // ProudNetSrcBinaryWriterExtensions.WriteProudString(writer, address, false) emiter.LoadArgument(1); emiter.LoadLocal(address); emiter.LoadConstant(false); emiter.Call(ReflectionHelper.GetMethod((BinaryWriter x) => x.WriteProudString(default(string), default(bool)))); // writer.Write(port) emiter.CallSerializerForType(typeof(ushort), port); } }
public override void Emit <T>(Emit <T> emitter) { emitter.BranchIfEqual(_label); }
void ExpectChar(char c) { var gotChar = Emit.DefineLabel(); RawReadChar(() => ThrowExpected(c)); // int Emit.LoadConstant((int)c); // int int Emit.BranchIfEqual(gotChar); // --empty-- ThrowExpected(c); // --empty-- Emit.MarkLabel(gotChar); // --empty-- }
public static Emit <Func <IEnumerable <object>, IEnumerable <T> > > GenerateMapper <T>() { Type type = typeof(T); Emit <Func <IEnumerable <object>, IEnumerable <T> > > emit = null; if (_mappers.ContainsKey(type.FullName)) { emit = (Emit <Func <IEnumerable <object>, IEnumerable <T> > >)_mappers[type.FullName]; } else { ConstructorInfo listConstructor = typeof(List <T>).GetConstructor(new Type[] { }); MethodInfo listAdd = typeof(List <T>).GetMethod("Add", new Type[] { typeof(T) }); Emit <Func <IEnumerable <object>, IEnumerable <T> > > emiter = Emit <Func <IEnumerable <object>, IEnumerable <T> > > .NewDynamicMethod(type.Name + "Mapper"); var enumeratorLocal = emiter.DeclareLocal <IEnumerator <object> >("enumerator"); var listLocal = emiter.DeclareLocal <List <T> >("list"); var cacheLocal = emiter.DeclareLocal <IDictionary <object, object> >("cache"); var loopFinishedLabel = emiter.DefineLabel("loopFinished"); var loopCheckLabel = emiter.DefineLabel("loopCheck"); var loopBeginLabel = emiter.DefineLabel("loopBegin"); var finallyFinishedLabel = emiter.DefineLabel("finallyFinished"); var isNullLabel = emiter.DefineLabel("isNull"); emiter.NewObject(listConstructor); emiter.StoreLocal(listLocal); emiter.NewObject(DictionaryConstructor_Object_Object); emiter.StoreLocal(cacheLocal); emiter.LoadArgument(0); emiter.CallVirtual(IEnumerable_Object_GetEnumerator); emiter.StoreLocal(enumeratorLocal); //try { var exceptionBlock = emiter.BeginExceptionBlock(); emiter.Branch(loopCheckLabel); emiter.MarkLabel(loopBeginLabel); emiter.LoadLocal(listLocal); emiter.LoadLocal(enumeratorLocal); emiter.CallVirtual(IEnumerator_Object_GetCurrent); emiter.CastClass <IDictionary <string, object> >(); emiter.LoadLocal(cacheLocal); emiter.LoadConstant(""); emiter.Call(GenerateRowMapper(type)); // var rowResult = rowMapper ( row, cache, depthString = "" ); emiter.Duplicate(); emiter.LoadNull(); emiter.BranchIfEqual(isNullLabel); emiter.CastClass(typeof(T)); emiter.Call(listAdd); // listLocal.Add((T)rowResult); emiter.Branch(loopCheckLabel); emiter.MarkLabel(isNullLabel); emiter.Pop(); emiter.Pop(); emiter.MarkLabel(loopCheckLabel); emiter.LoadLocal(enumeratorLocal); emiter.CallVirtual(IEnumerator_MoveNext); emiter.BranchIfTrue(loopBeginLabel); emiter.Leave(loopFinishedLabel); //} //finallY { var finallyBlock = emiter.BeginFinallyBlock(exceptionBlock); emiter.LoadNull(); emiter.LoadLocal(enumeratorLocal); emiter.CompareEqual(); emiter.BranchIfTrue(finallyFinishedLabel); emiter.LoadLocal(enumeratorLocal); emiter.CallVirtual(IEnumerator_Dispose); emiter.MarkLabel(finallyFinishedLabel); emiter.EndFinallyBlock(finallyBlock); emiter.EndExceptionBlock(exceptionBlock); //} emiter.MarkLabel(loopFinishedLabel); emiter.LoadLocal(listLocal); emiter.Return(); // return listLocal; _mapperDelegates.Add(type.FullName, emiter.CreateDelegate()); _mappers.Add(type.FullName, emiter); emit = emiter; } return(emit); }