Beispiel #1
0
        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();
 }
Beispiel #3
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);
        }