Ejemplo n.º 1
0
 public override void Emit <T>(Emit <T> emitter)
 {
     _finBlock.Block = emitter.BeginFinallyBlock(_exBlock.Block);
 }
Ejemplo n.º 2
0
        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);
        }