void CreateSaver()
{
var method = ILBuilder.Instance.NewMethod<Action<IInternalObjectDBTransaction, DBObjectMetadata, AbstractBufferedWriter, object>>(
$"Saver_{Name}");
var ilGenerator = method.Generator;
ilGenerator.DeclareLocal(ClientType);
ilGenerator
.Ldarg(3)
.Castclass(ClientType)
.Stloc(0);
var anyNeedsCtx = ClientTableVersionInfo.NeedsCtx();
if (anyNeedsCtx)
{
ilGenerator.DeclareLocal(typeof(IWriterCtx));
ilGenerator
.Ldarg(0)
.Ldarg(2)
.Newobj(() => new DBWriterCtx(null, null))
.Stloc(1);
}
var props = ClientType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
for (int i = 0; i < ClientTableVersionInfo.FieldCount; i++)
{
var field = ClientTableVersionInfo[i];
var getter = props.First(p => GetPersistantName(p) == field.Name).GetGetMethod(true);
Action<IILGen> writerOrCtx;
var handler = field.Handler.SpecializeSaveForType(getter.ReturnType);
if (handler.NeedsCtx())
writerOrCtx = il => il.Ldloc(1);
else
writerOrCtx = il => il.Ldarg(2);
handler.Save(ilGenerator, writerOrCtx, il =>
{
il.Ldloc(0).Callvirt(getter);
_tableInfoResolver.TypeConvertorGenerator.GenerateConversion(getter.ReturnType,
handler.HandledType())(il);
});
}
ilGenerator
.Ret();
var saver = method.Create();
Interlocked.CompareExchange(ref _saver, saver, null);
}