public static Expression GenerateInjectCtor(Type t, ConstructorInfo constructor, Type injectType)
        {
            LabelTarget returnTarget = Expression.Label(t, "returnLable");

            return(Expression.Block(
                       //if (reader.PeekIsNull())
                       //      goto label;
                       Expression.IfThen(CommonExpressionMeta.Call_Reader_TryReadNull, Expression.Return(returnTarget, Expression.Default(t))),
                       //return new Ctor(context.option.FormatterResolver.GetFormatter<injectType>().Deserialize(ref reader,option));
                       Expression.Return(returnTarget, Expression.New(constructor, CommonExpressionMeta.Call_DeserializeContextOptionResolver_GetFormatterWithVerify_Deserialize(injectType))),
                       //label default(T)
                       Expression.Label(returnTarget, Expression.Default(t))
                       ));
        }
        private static Expression BuildSizeCore(Type type, ObjectSerializationInfo serializationInfo, ParameterExpression instance)
        {
            List <Expression> ary          = new List <Expression>();
            LabelTarget       returnTarget = Expression.Label(typeof(int), "returnLable");

            if (!type.IsValueType)
            {
                //if (value==null)
                //     goto label: 1;
                ary.Add(CommonExpressionMeta.Block_IfNullSize(instance, type, returnTarget));
            }

            ParameterExpression size = Expression.Variable(typeof(int));

            SerializeMemberInfo[] mems = serializationInfo.SerializeMemberInfos;
            if (mems.Length == 0)
            {
                ary.Add(Expression.Assign(size, Expression.Constant(Array3Cache.Empty.Length)));
            }
            else
            {
                int maxLen = mems[mems.Length - 1].KeyIndex + 1;
                ary.Add(Expression.Assign(size, Expression.Constant(BssomBinaryPrimitives.Array3HeaderSize(maxLen))));

                FieldInfo memFormatters = serializationInfo.StoreMemberFormatterInstances();
                int       nullNumber    = 0;
                int       realIndex     = 0;
                for (int i = 0; i < maxLen; i++)
                {
                    if (mems[realIndex].KeyIndex != i)
                    {
                        nullNumber++;
                    }
                    else
                    {
                        //Size(mem.Value)
                        ary.Add(SpecialCodeGenExpression.SizeValues(mems[realIndex], instance, size, memFormatters));
                        realIndex++;
                    }
                }
                if (nullNumber > 0)
                {
                    ary.Add(Expression.AddAssign(size, Expression.Constant(nullNumber * BssomBinaryPrimitives.NullSize)));
                }
            }

            ary.Add(Expression.Label(returnTarget, size));

            return(Expression.Block(new ParameterExpression[] { size }, ary));
        }
Example #3
0
        public static void GenerateDeserializeWithIDictionaryEmptyCtor()
        {
            /*
             * var map = MapFormatterHelper.Deserialize(ref reader,ref context);
             * if (map == null)
             *    return null;
             * context.option.Security.DepthStep(ref reader);
             * T t = new T();
             * Deserialize(IEnumerable<KeyValuePair<TKey, TValue>> pair,(ICollection<KeyValuePair<TKey, TValue>>)t);
             * reader = map.Reader; context = map.Context;
             * reader.Seek(map.EndPos);
             * context.Depth--;
             * return t;
             */

            ArrayPack <Expression> ary       = new ArrayPack <Expression>(10);
            Type                t            = typeof(T);
            LabelTarget         returnTarget = Expression.Label(t, "returnLable");
            ParameterExpression map          = Expression.Variable(typeof(IMapDataSource <,>).MakeGenericType(typeof(object), typeof(object)));

            //map = MapFormatterHelper.Deserialize(ref reader,ref context);
            ary.Add(Expression.Assign(map, CommonExpressionMeta.Call_MapFormatterHelper_Deserialize(typeof(object), typeof(object))));
            //if (map == null)
            //      goto label;
            ary.Add(Expression.IfThen(Expression.Equal(map, Expression.Constant(null, map.Type)), Expression.Return(returnTarget, Expression.Default(t))));
            //context.option.Security.DepthStep(ref reader);
            ary.Add(CommonExpressionMeta.Call_DeserializeContext_Option_Security_DepthStep);
            //T t = new T();
            ParameterExpression instance = Expression.Variable(t);

            ary.Add(Expression.Assign(instance, Expression.New(t)));
            //MapFormatterHelper.FillData(map,(IDictionary)t)
            ary.Add(Expression.Call(null, typeof(MapFormatterHelper).GetMethod(nameof(MapFormatterHelper.FillIDictionaryData), BindingFlags.Public | BindingFlags.Static), map, Expression.Convert(instance, typeof(IDictionary))));

            //reader = map.Reader; context = map.Context;
            ary.Add(CommonExpressionMeta.Block_MapReaderAndContextAssignLocalReaderAndContext(map));
            //reader.Seek(map.EndPos);
            ary.Add(CommonExpressionMeta.Call_Reader_BufferSeek(Expression.Property(map, nameof(IMapDataSource <int, int> .EndPosition))));
            //context.Depth--;
            ary.Add(CommonExpressionMeta.Call_DeserializeContext_Depth_DecrementAssign);
            //return t;
            ary.Add(Expression.Return(returnTarget, instance));
            //label default(T)
            ary.Add(Expression.Label(returnTarget, instance));

            BlockExpression block = Expression.Block(new ParameterExpression[] { map, instance }, ary.GetArray());

            Deserialize = Expression.Lambda <Deserialize <T> >(block, CommonExpressionMeta.Par_Reader, CommonExpressionMeta.Par_DeserializeContext).Compile();
        }
        private static Expression BuildDeserializeCore(Type t, ObjectSerializationInfo serializationInfo)
        {
            List <Expression> ary          = new List <Expression>();
            LabelTarget       returnTarget = Expression.Label(t, "returnLable");
            //int num;
            ParameterExpression num = Expression.Variable(typeof(int), "num");
            //int for-i;
            ParameterExpression forVariable = Expression.Variable(typeof(int), "i");

            //context.option.Security.DepthStep(ref reader);
            ary.Add(CommonExpressionMeta.Call_DeserializeContext_Option_Security_DepthStep);

            //if(reader.TryReadNullWithEnsureBuildInType(BssomType.Array3))
            //      return default(t);
            ary.Add(Expression.IfThen(CommonExpressionMeta.Call_Reader_TryReadNullWithEnsureBuildInType(BssomType.Array3),
                                      Expression.Return(returnTarget, Expression.Default(t))));

            //T t = new T();
            ParameterExpression instance = Expression.Parameter(t, "instance");

            if (serializationInfo.IsDefaultNoArgsCtor)
            {
                ary.Add(Expression.Assign(instance, Expression.New(t)));
            }
            else
            {
                ParameterInfo[] parInfos = serializationInfo.BestmatchConstructor.GetParameters();
                Expression[]    pars     = new Expression[parInfos.Length];
                if (serializationInfo.ConstructorParametersIsDefaultValue)
                {
                    for (int i = 0; i < parInfos.Length; i++)
                    {
                        pars[i] = Expression.Default(parInfos[i].ParameterType);
                    }
                    ary.Add(Expression.Assign(instance, Expression.New(serializationInfo.BestmatchConstructor, pars)));
                }
                else
                {
                    object[] cps = serializationInfo.ConstructorParameters;
                    for (int i = 0; i < parInfos.Length; i++)
                    {
                        pars[i] = Expression.Constant(cps[i], parInfos[i].ParameterType);
                    }
                    ary.Add(Expression.Assign(instance, Expression.New(serializationInfo.BestmatchConstructor, pars)));
                }
            }

            //reader.SkipVariableNumber()
            ary.Add(CommonExpressionMeta.Call_Reader_SkipVariableNumber);
            //num = reader.ReadVariableNumber()
            ary.Add(Expression.Assign(num, CommonExpressionMeta.Call_Reader_ReadVariableNumber));
            //i = 0;
            ary.Add(Expression.Assign(forVariable, Expression.Constant(0)));

            var members = serializationInfo.SerializeMemberInfos;

            if (members.Length > 0)
            {
                //reader.Buffer.Seek(offsetSegment, Current)
                ary.Add(CommonExpressionMeta.Call_Reader_BufferSeek(Expression.Convert(Expression.Multiply(num, Expression.Constant(BssomBinaryPrimitives.FixUInt32NumberSize)), typeof(Int64)), BssomSeekOrgin.Current));
                //switch(i)
                //  case 0: instance.Key0 = readValue();
                //  case 3: instance.Key1 = readValue();
                //  case 5: instance.Key2 = readValue();
                //  default: skipObj();
                FieldInfo    memFormatters = serializationInfo.StoreMemberFormatterInstances();
                SwitchCase[] switchCases   = new SwitchCase[members.Length];
                for (int i = 0; i < members.Length; i++)
                {
                    switchCases[i] = Expression.SwitchCase(SpecialCodeGenExpression.ReadValues(members[i], instance, memFormatters), Expression.Constant(members[i].KeyIndex));
                }
                Expression content = Expression.Switch(
                    typeof(void),
                    forVariable,
                    CommonExpressionMeta.Call_Reader_SkipObject,
                    null,
                    switchCases
                    );

                ary.Add(For(forVariable, Expression.LessThan(forVariable, num), Expression.Assign(forVariable, Expression.Add(forVariable, Expression.Constant(1))), content));
            }
            //context.Depth--;
            ary.Add(CommonExpressionMeta.Call_DeserializeContext_Depth_DecrementAssign);

            ary.Add(Expression.Return(returnTarget, instance));

            ary.Add(Expression.Label(returnTarget, instance));

            return(Expression.Block(new ParameterExpression[] { instance, num, forVariable, }, ary));
        }
        private static Expression BuildSerializeCore(Type type, ObjectSerializationInfo serializationInfo, ParameterExpression instance)
        {
            List <Expression> ary          = new List <Expression>();
            LabelTarget       returnTarget = Expression.Label(typeof(void), "returnLable");

            if (!type.IsValueType)
            {
                //if (value==null)
                //     writer.WriteNull(); goto label;
                ary.Add(CommonExpressionMeta.Block_IfNullWriteNullWithReturn(instance, type, returnTarget));
            }

            ParameterExpression[] variables = null;
            var keys = serializationInfo.SerializeMemberInfos;

            if (keys.Length == 0)
            {
                //writer.WriteRaw(Array3Cache._EmptyBuffer);
                ary.Add(CommonExpressionMeta.Call_WriteRaw(Expression.Field(null, Array3Cache._EmptyBuffer)));
            }
            else
            {
                int  maxLen = keys[keys.Length - 1].KeyIndex + 1;
                Type stackallocBlockType = StackallocBlockProvider.GetOrCreateType(maxLen * sizeof(uint));
                //long position;
                //Block{size} block;
                //IntPtr blockPtr;
                variables    = new ParameterExpression[3];
                variables[0] = Expression.Variable(typeof(long), "elementOffPosition");
                variables[1] = Expression.Variable(stackallocBlockType, "block");
                variables[2] = Expression.Variable(typeof(IntPtr), "blockPtr");

                //position = writer.WriteArray3Header(keys.Length);
                ary.Add(Expression.Assign(variables[0], CommonExpressionMeta.Call_WriteArray3Header(maxLen)));
                //block = new Block{size}();
                ary.Add(Expression.Assign(variables[1], Expression.New(stackallocBlockType)));
                //blockPtr = AsPointer(ref block);
                ary.Add(Expression.Assign(variables[2], ExpressionTreeAux.AsPointerExpression(variables[1])));

                //0,3,5  --> maxLen = 6
                FieldInfo memFormatters = serializationInfo.StoreMemberFormatterInstances();
                int       realIndex     = 0;


                for (int i = 0; i < maxLen; i++)
                {
                    //StackallocBlockHelper.WriteUInt(blockPtr, 0, (uint)(writer.Position - position));
                    ary.Add(Expression.Call(null, StackallocBlockHelper._WriteUIntMethodInfo, variables[2], Expression.Constant(i), Expression.Convert(Expression.Subtract(CommonExpressionMeta.Field_WriterPos, variables[0]), typeof(uint))));

                    if (keys[realIndex].KeyIndex != i)
                    {
                        //WriteNull()
                        ary.Add(CommonExpressionMeta.Call_Writer_WriteNull);
                    }
                    else
                    {
                        //Writer(mem.Value)
                        ary.Add(SpecialCodeGenExpression.WriteValues(keys[realIndex], instance, memFormatters));
                        realIndex++;
                    }
                }

                //writer.WriteBackArray3Header(blockPtr)
                ary.Add(CommonExpressionMeta.Call_WriteBackArray3Header(variables[0], variables[2], maxLen));
            }

            ary.Add(Expression.Label(returnTarget));

            if (variables != null)
            {
                return(Expression.Block(variables, ary));
            }
            return(Expression.Block(ary));
        }
Example #6
0
 public static void GenerateInjectCtor(ConstructorInfo constructor, Type injectType)
 {
     Deserialize = Expression.Lambda <Deserialize <T> >(CommonExpressionMeta.GenerateInjectCtor(typeof(T), constructor, injectType), CommonExpressionMeta.Par_Reader, CommonExpressionMeta.Par_DeserializeContext).Compile();
 }