PushDeserializedObjectsCollectionOntoStack() 공개 메소드

public PushDeserializedObjectsCollectionOntoStack ( ) : void
리턴 void
예제 #1
0
        private static void GenerateReadDelegate(ReaderGenerationContext context, Type type, Action pushObjectIdOntoStackAction)
        {
            var invocationListLengthLocal = context.Generator.DeclareLocal(typeof(int));
            var targetLocal = context.Generator.DeclareLocal(typeof(object));

            GenerateReadPrimitive(context, typeof(int));
            context.Generator.StoreLocalValueFromStack(invocationListLengthLocal);

            GeneratorHelper.GenerateLoop(context, invocationListLengthLocal, cl =>
            {
                GenerateReadField(context, typeof(object));
                context.Generator.StoreLocalValueFromStack(targetLocal);

                GenerateReadMethod(context);
                context.Generator.PushTypeOntoStack(type);
                context.Generator.PushLocalValueOntoStack(targetLocal);
                context.PushDeserializedObjectsCollectionOntoStack();
                pushObjectIdOntoStackAction();

                context.Generator.GenerateCodeCall <MethodInfo, Type, object, AutoResizingList <object>, int>((method, t, target, deserializedObjects, objectId) =>
                {
                    var del = Delegate.CreateDelegate(t, target, method);
                    deserializedObjects[objectId] = Delegate.Combine((Delegate)deserializedObjects[objectId], del);
                });
            });
        }
        private static void SaveNewDeserializedObject(ReaderGenerationContext context, LocalBuilder objectIdLocal, Action generateNewObject)
        {
            context.PushDeserializedObjectsCollectionOntoStack();
            context.Generator.PushLocalValueOntoStack(objectIdLocal);

            generateNewObject();

            context.Generator.Emit(OpCodes.Call, Helpers.GetMethodInfo <AutoResizingList <object> >(x => x.SetItem(0, null)));
        }
        private static void GenerateTouchObject(ReaderGenerationContext context, Type formalType)
        {
            var finish = context.Generator.DefineLabel();

            context.PushObjectIdOntoStack();
            context.PushDeserializedObjectsCollectionOntoStack();
            context.Generator.PushPropertyValueOntoStack <AutoResizingList <object>, int>(x => x.Count);
            // if (refId < deserializedObjects.Count) return;
            context.Generator.Emit(OpCodes.Blt, finish);

            if (CreateObjectGenerator.TryFillBody(context.Generator, formalType, context.TreatCollectionAsUserObject, x =>
            {
                context.PushObjectReaderOntoStack();
                context.PushObjectIdOntoStack();
            }))
            {
                context.Generator.Call <ObjectReader>(x => x.SetObjectByReferenceId(0, null));
            }

            context.Generator.MarkLabel(finish);
        }
 internal static void GenerateReadNotPrecreated(ReaderGenerationContext context, Type formalType, Action pushObjectIdOntoStackAction)
 {
     if (formalType.IsValueType)
     {
         context.PushDeserializedObjectsCollectionOntoStack();
         pushObjectIdOntoStackAction();
         GenerateReadField(context, formalType, true);
         context.Generator.Emit(OpCodes.Call, Helpers.GetMethodInfo <AutoResizingList <object> >(x => x.SetItem(0, null)));
     }
     else if (formalType.IsArray)
     {
         GenerateReadArray(context, formalType, pushObjectIdOntoStackAction);
     }
     else if (typeof(MulticastDelegate).IsAssignableFrom(formalType))
     {
         GenerateReadDelegate(context, formalType, pushObjectIdOntoStackAction);
     }
     else
     {
         throw new InvalidOperationException(InternalErrorMessage + "GenerateReadNotPrecreated");
     }
 }
        protected override void InnerGenerate(ReaderGenerationContext context)
        {
            var finish       = context.Generator.DefineLabel();
            var createdLocal = context.Generator.DeclareLocal(typeof(object));

            context.PushObjectIdOntoStack();
            context.PushDeserializedObjectsCollectionOntoStack();
            context.Generator.PushPropertyValueOntoStack <AutoResizingList <object>, int>(x => x.Count);
            context.Generator.Emit(OpCodes.Blt, finish);

            if (CreateObjectGenerator.TryFillBody(context.Generator, type, treatCollectionAsUserObject))
            {
                context.Generator.StoreLocalValueFromStack(createdLocal);
                context.PushObjectReaderOntoStack();
                context.PushObjectIdOntoStack();
                context.Generator.PushLocalValueOntoStack(createdLocal);
                context.Generator.Call <ObjectReader>(x => x.SetObjectByReferenceId(0, null));
            }
            else if (type.IsArray)
            {
                var isMultidimensional = type.GetArrayRank() > 1;
                var elementFormalType  = type.GetElementType();

                var rankLocal    = context.Generator.DeclareLocal(typeof(int));
                var lengthsLocal = isMultidimensional ? context.Generator.DeclareLocal(typeof(int[])) : context.Generator.DeclareLocal(typeof(int));

                context.PushObjectReaderOntoStack();
                context.PushObjectIdOntoStack();

                ReadMethodGenerator.GenerateReadPrimitive(context, typeof(int));
                context.Generator.StoreLocalValueFromStack(rankLocal);
                if (isMultidimensional)
                {
                    context.Generator.PushLocalValueOntoStack(rankLocal);
                    context.Generator.Emit(OpCodes.Newarr, typeof(int));
                    context.Generator.StoreLocalValueFromStack(lengthsLocal); // create an array for keeping the lengths of each dimension

                    GeneratorHelper.GenerateLoop(context, rankLocal, i =>
                    {
                        context.Generator.PushLocalValueOntoStack(lengthsLocal);
                        context.Generator.PushLocalValueOntoStack(i);
                        ReadMethodGenerator.GenerateReadPrimitive(context, typeof(int));
                        context.Generator.Emit(OpCodes.Stelem, typeof(int)); // populate the lengths with values read from stream
                    });
                }
                else
                {
                    ReadMethodGenerator.GenerateReadPrimitive(context, typeof(int));
                    context.Generator.StoreLocalValueFromStack(lengthsLocal);
                }

                context.Generator.PushTypeOntoStack(elementFormalType);
                context.Generator.PushLocalValueOntoStack(lengthsLocal);

                if (isMultidimensional)
                {
                    context.Generator.Call(() => Array.CreateInstance(null, new int[0]));
                }
                else
                {
                    context.Generator.Call(() => Array.CreateInstance(null, 0));
                }

                context.Generator.Call <ObjectReader>(x => x.SetObjectByReferenceId(0, null));
            }
            else if (type == typeof(string))
            {
                context.PushObjectReaderOntoStack();
                context.PushObjectIdOntoStack();
                ReadMethodGenerator.GenerateReadPrimitive(context, typeof(string));
                context.Generator.Call <ObjectReader>(x => x.SetObjectByReferenceId(0, null));

                var field = Helpers.GetFieldInfo <ObjectReader, int>(x => x.objectsWrittenInlineCount);

                context.PushObjectReaderOntoStack();
                context.Generator.Emit(OpCodes.Dup);
                context.Generator.Emit(OpCodes.Ldfld, field);
                context.Generator.PushIntegerOntoStack(1);
                context.Generator.Emit(OpCodes.Add);
                context.Generator.Emit(OpCodes.Stfld, field);
            }
            else
            {
                ReadMethodGenerator.GenerateReadNotPrecreated(context, type, context.PushObjectIdOntoStack);

                var field = Helpers.GetFieldInfo <ObjectReader, int>(x => x.objectsWrittenInlineCount);

                context.PushObjectReaderOntoStack();
                context.Generator.Emit(OpCodes.Dup);
                context.Generator.Emit(OpCodes.Ldfld, field);
                context.Generator.PushIntegerOntoStack(1);
                context.Generator.Emit(OpCodes.Add);
                context.Generator.Emit(OpCodes.Stfld, field);
            }

            context.Generator.MarkLabel(finish);
        }