protected override bool InnerGenerate(WriterGenerationContext context) { var value = new Variable(1); WriteMethodGenerator.GenerateWriteDeferredReference(context, value, type); return(true); }
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); }
private Action<ObjectWriter, PrimitiveWriter, object> PrepareWriteMethod(Type actualType, int surrogateId) { if(surrogateId == -1) { var specialWrite = LinkSpecialWrite(actualType); if(specialWrite != null) { // linked methods are not added to writeMethodCache, there's no point return specialWrite; } } if(!isGenerating) { if(surrogateId != -1) { return (ow, pw, o) => ow.InvokeCallbacksAndWriteObject(surrogatesForObjects.GetByIndex(surrogateId).DynamicInvoke(new [] { o })); } return WriteObjectUsingReflection; } var method = new WriteMethodGenerator(actualType, treatCollectionAsUserObject, surrogateId, Helpers.GetFieldInfo<ObjectWriter, SwapList>(x => x.surrogatesForObjects), Helpers.GetMethodInfo<ObjectWriter>(x => x.InvokeCallbacksAndWriteObject(null))).Method; var result = (Action<ObjectWriter, PrimitiveWriter, object>)method.CreateDelegate(typeof(Action<ObjectWriter, PrimitiveWriter, object>)); return result; }