public void EmitDeserialize(Emit emiter, Local value) { var elementType = value.LocalType.GetElementType(); //value = new Type[100]; emiter.LoadConstant(100); emiter.NewArray(elementType); emiter.StoreLocal(value); var loop = emiter.DefineLabel(); var loopCheck = emiter.DefineLabel(); using (var ex = emiter.DeclareLocal <Exception>("_ex")) using (var element = emiter.DeclareLocal(elementType, "element")) using (var i = emiter.DeclareLocal <int>("i")) { emiter.MarkLabel(loop); var eb = emiter.BeginExceptionBlock(); if (_compiler != null) { _compiler.EmitDeserialize(emiter, element); } else if (_serializer != null) { emiter.CallDeserializer(_serializer, element); } else { emiter.CallDeserializerForType(elementType, element); } var cb = emiter.BeginCatchBlock <Exception>(eb); emiter.StoreLocal(ex); emiter.EndCatchBlock(cb); emiter.EndExceptionBlock(eb); // value[i] = element emiter.LoadLocal(value); emiter.LoadLocal(i); emiter.LoadLocal(element); emiter.StoreElement(elementType); // ++i emiter.LoadLocal(i); emiter.LoadConstant(1); emiter.Add(); emiter.StoreLocal(i); // i < length emiter.MarkLabel(loopCheck); emiter.LoadLocal(i); emiter.LoadConstant(100); emiter.BranchIfLess(loop); } }
public override void Emit <T>(Emit <T> emitter) { _block.Block = emitter.BeginExceptionBlock(); }
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); }