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); }
private void GenerateDesurrogate(ReaderGenerationContext context, int factoryId) { if (factoryId == -1) { return; } var desurrogatedObjectLocal = context.Generator.DeclareLocal(typeof(object)); // obtain surrogate factory context.PushObjectReaderOntoStack(); context.Generator.PushFieldValueOntoStack <ObjectReader, SwapList>(x => x.objectsForSurrogates); context.Generator.PushIntegerOntoStack(factoryId); context.Generator.Call <SwapList>(x => x.GetByIndex(0)); // recreate an object from the surrogate var delegateType = typeof(Func <,>).MakeGenericType(type, typeof(object)); context.Generator.Emit(OpCodes.Castclass, delegateType); context.PushDeserializedObjectOntoStack(context.PushObjectIdOntoStack); context.Generator.Emit(OpCodes.Call, delegateType.GetMethod("Invoke")); context.Generator.StoreLocalValueFromStack(desurrogatedObjectLocal); // clone context context.PushObjectReaderOntoStack(); context.Generator.PushFieldValueOntoStack <ObjectReader, Serializer.ReadMethods>(x => x.readMethods); context.Generator.PushFieldValueOntoStack <Serializer.ReadMethods, DynamicMethodProvider <CloneMethodDelegate> >(x => x.cloneContentMehtodsProvider); context.Generator.PushLocalValueOntoStack(desurrogatedObjectLocal); context.Generator.Call <object>(x => x.GetType()); context.Generator.Call <DynamicMethodProvider <CloneMethodDelegate> >(x => x.GetOrCreate(typeof(void))); context.Generator.PushLocalValueOntoStack(desurrogatedObjectLocal); context.PushDeserializedObjectOntoStack(context.PushObjectIdOntoStack, true); context.Generator.Call <CloneMethodDelegate>(x => x.Invoke(null, null)); //remove object reference from surrogatesWhileReading collection context.PushObjectReaderOntoStack(); context.Generator.PushFieldValueOntoStack <ObjectReader, OneToOneMap <int, object> >(x => x.surrogatesWhileReading); context.PushObjectIdOntoStack(); context.Generator.Call <OneToOneMap <int, object> >(x => x.Remove(0)); }
private static void GenerateReadObjectInner(ReaderGenerationContext context, Type formalType) { var objectIdLocal = context.Generator.DeclareLocal(typeof(int)); context.PushObjectIdOntoStack(); context.Generator.StoreLocalValueFromStack(objectIdLocal); GenerateTouchObject(context, formalType); switch (ObjectReader.GetCreationWay(formalType, context.TreatCollectionAsUserObject)) { case ObjectReader.CreationWay.Null: GenerateReadNotPrecreated(context, formalType, objectIdLocal); break; case ObjectReader.CreationWay.DefaultCtor: GenerateUpdateElements(context, formalType, objectIdLocal); break; case ObjectReader.CreationWay.Uninitialized: GenerateUpdateFields(context, formalType, objectIdLocal); break; } }
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); }