PushObjectWriterOntoStack() public method

public PushObjectWriterOntoStack ( ) : void
return void
示例#1
0
        private static void GenerateInvokeCallbacksAndExecute(WriterGenerationContext context, bool generatePreSerializationCallback, bool generatePostSerializationCallback, Variable valueLocal, Type type, Action <WriterGenerationContext> bodyBuilder)
        {
            if (generatePreSerializationCallback || generatePostSerializationCallback)
            {
                context.Generator.BeginExceptionBlock();
            }

            if (generatePreSerializationCallback)
            {
                context.PushObjectWriterOntoStack();
                context.Generator.PushFieldValueOntoStack <ObjectWriter, Action <object> >(x => x.preSerializationCallback);
                context.Generator.PushVariableOntoStack(valueLocal);
                context.Generator.Call <Action <object> >(x => x.Invoke(null));
            }

            bodyBuilder(context);

            if (generatePreSerializationCallback || generatePostSerializationCallback)
            {
                context.Generator.BeginFinallyBlock();
            }

            if (generatePostSerializationCallback)
            {
                context.PushObjectWriterOntoStack();
                context.Generator.PushFieldValueOntoStack <ObjectWriter, Action <object> >(x => x.postSerializationCallback);
                context.Generator.PushVariableOntoStack(valueLocal);
                context.Generator.Call <Action <object> >(x => x.Invoke(null));
            }

            if (generatePreSerializationCallback || generatePostSerializationCallback)
            {
                context.Generator.EndExceptionBlock();
            }
        }
示例#2
0
        protected override bool InnerGenerate(WriterGenerationContext context)
        {
            Variable value;

            if (type.IsValueType)
            {
                var valueLocal = context.Generator.DeclareLocal(type);
                context.Generator.Emit(OpCodes.Ldarg_1);
                context.Generator.Emit(OpCodes.Unbox_Any, type);
                context.Generator.StoreLocalValueFromStack(valueLocal);

                value = new Variable(valueLocal);
            }
            else
            {
                value = new Variable(1);
            }

            var objectForSurrogatesIndex = objectsForSurrogates == null ? -1 : objectsForSurrogates.FindMatchingIndex(type);

            context.PushPrimitiveWriterOntoStack();
            context.Generator.PushIntegerOntoStack(objectForSurrogatesIndex != -1 ? 1 : 0);
            context.Generator.Call <PrimitiveWriter>(x => x.Write(false));

            if (objectForSurrogatesIndex != -1)
            {
                context.PushObjectWriterOntoStack();
                context.Generator.Emit(OpCodes.Dup);
                context.Generator.PushFieldValueOntoStack <ObjectWriter, SwapList>(x => x.objectsForSurrogates);
                context.Generator.PushIntegerOntoStack(objectForSurrogatesIndex);
                context.Generator.Call <SwapList>(x => x.GetByIndex(0));

                var delegateType = typeof(Func <,>).MakeGenericType(type, typeof(object));
                context.Generator.Emit(OpCodes.Castclass, delegateType);
                context.Generator.Emit(OpCodes.Ldarg_1);
                context.Generator.Emit(OpCodes.Call, delegateType.GetMethod("Invoke"));

                // here should be a primitive writer on a stack
                context.Generator.Call <object>(x => x.GetType());
                context.Generator.Call <ObjectWriter>(x => x.TouchAndWriteTypeId(typeof(void)));
                context.Generator.Emit(OpCodes.Pop);
            }

            if (WriteMethodGenerator.GenerateTryWriteObjectInline(context, generatePreSerializationCallback, generatePostSerializationCallback, value, type))
            {
                context.PushObjectWriterOntoStack();
                context.Generator.PushFieldValueOntoStack <ObjectWriter, HashSet <int> >(x => x.objectsWrittenInline);
                context.Generator.Emit(OpCodes.Ldarg_2); // reference identifier
                context.Generator.Call <HashSet <int> >(x => x.Add(0));
                context.Generator.Emit(OpCodes.Pop);
            }

            return(true);
        }
示例#3
0
        private static void GenerateWriteDelegate(WriterGenerationContext context, Variable valueLocal)
        {
            var array                  = context.Generator.DeclareLocal(typeof(Delegate[]));
            var loopLength             = context.Generator.DeclareLocal(typeof(int));
            var element                = context.Generator.DeclareLocal(typeof(Delegate));
            var delegateTargetLocal    = context.Generator.DeclareLocal(typeof(object));
            var delegateTargetVariable = new Variable(delegateTargetLocal);

            context.PushPrimitiveWriterOntoStack();

            context.PushObjectWriterOntoStack();
            context.Generator.PushVariableOntoStack(valueLocal);
            context.Generator.Call <ObjectWriter>(x => x.GetDelegatesWithNonTransientTargets(null));
            context.Generator.Emit(OpCodes.Castclass, typeof(Delegate[]));
            context.Generator.Emit(OpCodes.Dup);
            context.Generator.StoreLocalValueFromStack(array);

            // array refrence should be on the top of stack here
            context.Generator.Emit(OpCodes.Ldlen);
            context.Generator.Emit(OpCodes.Dup);
            context.Generator.StoreLocalValueFromStack(loopLength);

            // primitive writer should be on the stack
            // array length should be on the stack
            context.Generator.Call <PrimitiveWriter>(x => x.Write(0));

            GeneratorHelper.GenerateLoop(context, loopLength, c =>
            {
                context.Generator.PushLocalValueOntoStack(array);
                context.Generator.PushLocalValueOntoStack(c);
                context.Generator.Emit(OpCodes.Ldelem, element.LocalType);
                context.Generator.Emit(OpCodes.Dup);
                context.Generator.StoreLocalValueFromStack(element);

                // element reference should be on the stack
                context.Generator.PushPropertyValueOntoStack <MulticastDelegate, object>(x => x.Target);
                context.Generator.StoreLocalValueFromStack(delegateTargetLocal);

                GenerateWriteDeferredReference(context, delegateTargetVariable, typeof(object));

                context.PushObjectWriterOntoStack();
                context.Generator.PushPropertyValueOntoStack <ObjectWriter, IdentifiedElementsDictionary <MethodDescriptor> >(x => x.Methods);
                context.Generator.PushLocalValueOntoStack(element);
                context.Generator.PushPropertyValueOntoStack <MulticastDelegate, MethodInfo>(x => x.Method);
                context.Generator.Emit(OpCodes.Newobj, Helpers.GetConstructorInfo <MethodDescriptor>(typeof(MethodInfo)));
                context.Generator.Call <IdentifiedElementsDictionary <MethodDescriptor> >(x => x.TouchAndWriteId(null));
                context.Generator.Emit(OpCodes.Pop);
            });
        }
示例#4
0
        private void GenerateAddCallbackToInvokeList(WriterGenerationContext context, LocalBuilder valueLocal, Type actualType, Type attributeType)
        {
            var actionCtor      = typeof(Action).GetConstructor(new[] { typeof(object), typeof(IntPtr) });
            var addToListMethod = Helpers.GetMethodInfo <List <Action> >(x => x.Add(null));

            var methodsWithAttribute = Helpers.GetMethodsWithAttribute(attributeType, actualType).ToList();
            var count = methodsWithAttribute.Count;

            if (count > 0)
            {
                context.PushObjectWriterOntoStack();
                context.Generator.PushFieldValueOntoStack <ObjectWriter, List <Action> >(x => x.postSerializationHooks);
            }
            for (var i = 1; i < count; i++)
            {
                context.Generator.Emit(OpCodes.Dup);
            }
            foreach (var method in methodsWithAttribute)
            {
                // let's make the delegate
                if (method.IsStatic)
                {
                    context.Generator.Emit(OpCodes.Ldnull);
                }
                else
                {
                    context.Generator.PushLocalValueOntoStack(valueLocal);
                }
                context.Generator.Emit(OpCodes.Ldftn, method);
                context.Generator.Emit(OpCodes.Newobj, actionCtor);
                // and add it to invoke list
                context.Generator.Emit(OpCodes.Call, addToListMethod);
            }
        }
示例#5
0
        internal static void GenerateWriteDeferredReference(WriterGenerationContext context, Variable valueLocal, Type formalType)
        {
            var finish         = context.Generator.DefineLabel();
            var isNotNull      = context.Generator.DefineLabel();
            var isNotTransient = context.Generator.DefineLabel();

            context.Generator.PushVariableOntoStack(valueLocal);
            context.Generator.Emit(OpCodes.Brtrue_S, isNotNull);

            context.PushNullReferenceOnStack();
            context.Generator.Emit(OpCodes.Br, finish);

            context.Generator.MarkLabel(isNotNull);
            var formalTypeIsActualType = (formalType.Attributes & TypeAttributes.Sealed) != 0;

            if (!formalTypeIsActualType)
            {
                context.Generator.PushVariableOntoStack(valueLocal);
                context.Generator.Call(() => Helpers.IsTransient((object)null));

                context.Generator.Emit(OpCodes.Brfalse_S, isNotTransient);
                context.PushNullReferenceOnStack();
                context.Generator.Emit(OpCodes.Br, finish);

                context.Generator.MarkLabel(isNotTransient);
                context.PushObjectWriterOntoStack();
                context.Generator.PushVariableOntoStack(valueLocal);
                context.Generator.Call <ObjectWriter>(x => x.WriteDeferredReference(null));
            }
            else
            {
                if (Helpers.IsTransient(formalType))
                {
                    context.PushNullReferenceOnStack();
                }
                else
                {
                    context.PushObjectWriterOntoStack();
                    context.Generator.PushVariableOntoStack(valueLocal);
                    context.Generator.Call <ObjectWriter>(x => x.WriteDeferredReference(null));
                }
            }
            context.Generator.MarkLabel(finish);
        }
示例#6
0
        protected override bool InnerGenerate(WriterGenerationContext context)
        {
            var surrogateId = surrogatesForObjects.FindMatchingIndex(type);

            if (surrogateId == -1)
            {
                return(false);
            }

            var objVariable = new Variable(1);

            context.PushObjectWriterOntoStack();
            context.Generator.PushFieldValueOntoStack <ObjectWriter, SwapList>(x => x.surrogatesForObjects);
            context.Generator.PushIntegerOntoStack(surrogateId);
            context.Generator.Call <SwapList>(x => x.GetByIndex(0));

            // call surrogate factory to obtain surrogate object
            var delegateType = typeof(Func <,>).MakeGenericType(type, typeof(object));

            context.Generator.Emit(OpCodes.Castclass, delegateType);
            context.Generator.PushVariableOntoStack(objVariable);
            if (type.IsValueType)
            {
                context.Generator.Emit(OpCodes.Unbox_Any, type);
            }
            context.Generator.Emit(OpCodes.Call, delegateType.GetMethod("Invoke"));
            context.Generator.StoreVariableValueFromStack(objVariable);

            context.PushObjectWriterOntoStack();
            context.Generator.PushFieldValueOntoStack <ObjectWriter, ObjectIdentifier>(x => x.identifier);
            context.Generator.PushVariableOntoStack(objVariable); // object reference
            context.Generator.Emit(OpCodes.Ldarg_2);              // reference id
            context.Generator.Call <ObjectIdentifier>(x => x.SetIdentifierForObject(null, 0));

            context.Generator.PushVariableOntoStack(objVariable);

            return(true);
        }
示例#7
0
        protected override bool InnerGenerate(WriterGenerationContext context)
        {
            var result = false;

            var methods = Helpers.GetMethodsWithAttribute(typeof(PostSerializationAttribute), type).ToArray();

            foreach (var method in methods)
            {
                if (!method.IsStatic)
                {
                    context.Generator.Emit(OpCodes.Ldarg_1);
                    context.Generator.Emit(OpCodes.Castclass, method.ReflectedType);
                }
                if (method.IsVirtual)
                {
                    context.Generator.Emit(OpCodes.Callvirt, method);
                }
                else
                {
                    context.Generator.Emit(OpCodes.Call, method);
                }

                result = true;
            }

            methods = Helpers.GetMethodsWithAttribute(typeof(LatePostSerializationAttribute), type).ToArray();
            foreach (var method in methods)
            {
                context.PushObjectWriterOntoStack();
                context.Generator.PushFieldValueOntoStack <ObjectWriter, List <Action> >(x => x.postSerializationHooks);

                context.Generator.PushTypeOntoStack(typeof(Action));
                if (method.IsStatic)
                {
                    context.Generator.Emit(OpCodes.Ldnull);
                }
                else
                {
                    context.Generator.Emit(OpCodes.Ldarg_1);
                    context.Generator.Emit(OpCodes.Castclass, method.ReflectedType);
                }

                context.Generator.Emit(OpCodes.Ldtoken, method);
                if (method.DeclaringType.IsGenericType)
                {
                    context.Generator.Emit(OpCodes.Ldtoken, method.DeclaringType);
                    context.Generator.Emit(OpCodes.Call, Helpers.GetMethodInfo <object, MethodBase>(x => MethodBase.GetMethodFromHandle(new RuntimeMethodHandle(), new RuntimeTypeHandle())));
                }
                else
                {
                    context.Generator.Emit(OpCodes.Call, Helpers.GetMethodInfo <object, MethodBase>(x => MethodBase.GetMethodFromHandle(new RuntimeMethodHandle())));
                }

                context.Generator.Emit(OpCodes.Castclass, typeof(MethodInfo));
                context.Generator.Emit(OpCodes.Call, Helpers.GetMethodInfo <object, Delegate>(x => Delegate.CreateDelegate(null, null, method)));

                context.Generator.Emit(OpCodes.Castclass, typeof(Action));
                context.Generator.Emit(OpCodes.Call, Helpers.GetMethodInfo <List <Action> >(x => x.Add(null)));

                result = true;
            }

            return(result);
        }