public void GenerateLoad(IILGen ilGenerator, Action<IILGen> pushReader, Action<IILGen> pushCtx, Action<IILGen> pushDescriptor, Type targetType)
{
if (targetType == typeof(object))
{
var resultLoc = ilGenerator.DeclareLocal(typeof(DynamicObject), "result");
var labelNoCtx = ilGenerator.DefineLabel();
ilGenerator
.Do(pushDescriptor)
.Castclass(typeof(ObjectTypeDescriptor))
.Newobj(typeof(DynamicObject).GetConstructor(new[] { typeof(ObjectTypeDescriptor) }))
.Stloc(resultLoc)
.Do(pushCtx)
.BrfalseS(labelNoCtx)
.Do(pushCtx)
.Ldloc(resultLoc)
.Callvirt(() => default(ITypeBinaryDeserializerContext).AddBackRef(null))
.Mark(labelNoCtx);
var idx = 0;
foreach (var pair in _fields)
{
var idxForCapture = idx;
ilGenerator.Ldloc(resultLoc);
ilGenerator.LdcI4(idx);
pair.Value.GenerateLoadEx(ilGenerator, pushReader, pushCtx,
il =>
il.Do(pushDescriptor)
.LdcI4(idxForCapture)
.Callvirt(() => default(ITypeDescriptor).NestedType(0)), typeof(object), _typeSerializers.ConvertorGenerator);
ilGenerator.Callvirt(() => default(DynamicObject).SetFieldByIdxFast(0, null));
idx++;
}
ilGenerator
.Ldloc(resultLoc)
.Castclass(typeof(object));
}
else
{
var resultLoc = ilGenerator.DeclareLocal(targetType, "result");
var labelNoCtx = ilGenerator.DefineLabel();
ilGenerator
.Newobj(targetType.GetConstructor(Type.EmptyTypes))
.Stloc(resultLoc)
.Do(pushCtx)
.BrfalseS(labelNoCtx)
.Do(pushCtx)
.Ldloc(resultLoc)
.Callvirt(() => default(ITypeBinaryDeserializerContext).AddBackRef(null))
.Mark(labelNoCtx);
var props = targetType.GetProperties();
for (var idx = 0; idx < _fields.Count; idx++)
{
var idxForCapture = idx;
var pair = _fields[idx];
var prop = props.FirstOrDefault(p => GetPersitentName(p) == pair.Key);
if (prop == null || !_typeSerializers.IsSafeToLoad(prop.PropertyType))
{
pair.Value.GenerateSkipEx(ilGenerator, pushReader, pushCtx);
continue;
}
ilGenerator.Ldloc(resultLoc);
pair.Value.GenerateLoadEx(ilGenerator, pushReader, pushCtx,
il => il.Do(pushDescriptor).LdcI4(idxForCapture).Callvirt(() => default(ITypeDescriptor).NestedType(0)),
prop.PropertyType, _typeSerializers.ConvertorGenerator);
ilGenerator.Callvirt(prop.GetSetMethod());
}
ilGenerator.Ldloc(resultLoc);
}
}