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"); } }
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>(GenerateReadDelegateStaticHelper); }); }
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); }