Skip to content

Instantly share code, notes, and snippets.

@rpgmaker
Created February 8, 2012 16:34
Show Gist options
  • Save rpgmaker/1770873 to your computer and use it in GitHub Desktop.
Save rpgmaker/1770873 to your computer and use it in GitHub Desktop.
Emit List
static void WriteSerializerList(ILGenerator il, Type type,
MethodInfo getSetGetMethod, LocalBuilder msLocal,
List<Action<ILGenerator>> actions) {
var itemType = type.IsArray ? type.GetElementType() :
type.GetGenericArguments()[0];
var itemLocal = il.DeclareLocal(itemType);
var listLocal = il.DeclareLocal(type);
var indexLocal = il.DeclareLocal(typeof(int));
var startLabel = il.DefineLabel();
var endLabel = il.DefineLabel();
if (actions != null)
actions.ForEach(action => action(il));
il.Emit(OpCodes.Callvirt, getSetGetMethod);
il.Emit(OpCodes.Stloc, listLocal.LocalIndex);
il.Emit(OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Stloc, indexLocal.LocalIndex);
il.Emit(OpCodes.Br, startLabel);
il.MarkLabel(endLabel);
il.Emit(OpCodes.Ldloca_S, listLocal.LocalIndex);
il.Emit(OpCodes.Ldloca_S, indexLocal.LocalIndex);
il.Emit(OpCodes.Ldelem, itemType);
il.Emit(OpCodes.Stloc, itemLocal.LocalIndex);
if (itemType.IsComplexType()) {
var actionList = new List<Action<ILGenerator>>();
actionList.Add(msIL =>
{
msIL.Emit(OpCodes.Ldloc, itemLocal.LocalIndex);
});
WriteSerializerClass(il, getSetGetMethod, itemType, 1, msLocal, actionList);
} else {
il.Emit(OpCodes.Ldloc, msLocal.LocalIndex);
il.Emit(OpCodes.Ldloc, itemLocal.LocalIndex);
il.Emit(OpCodes.Ldc_I4, 1);
il.Emit(OpCodes.Call, WriteBytesMethod.MakeGenericMethod(itemType));
}
il.Emit(OpCodes.Ldloc_S, indexLocal.LocalIndex);
il.Emit(OpCodes.Ldc_I4_1);
il.Emit(OpCodes.Add);
il.Emit(OpCodes.Stloc_S, indexLocal.LocalIndex);
il.MarkLabel(startLabel);
il.Emit(OpCodes.Ldloc_S, indexLocal.LocalIndex);
il.Emit(OpCodes.Ldloc_S, itemLocal.LocalIndex);
il.Emit(OpCodes.Ldlen);
il.Emit(OpCodes.Conv_I4);
il.Emit(OpCodes.Blt, endLabel);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment