private void GenWriteObject(NodeTree node) { var members = node.Children; int obj = locman.AllocLocal(DicStrObjType); il.Emit(OpCodes.Castclass, typeof(DynamicAsset)); il.Emit(OpCodes.Ldfld, DynamicAsset_objects); il.EmitStloc(obj); for (int i = 0; i < members.Count; i++) { string membername = PrettifyName(members[i].Name); GenWriteUnknownType(members[i], requireUnboxing: true, loader: (cil) => { cil.EmitLdloc(obj); cil.Emit(OpCodes.Ldstr, membername); cil.Emit(OpCodes.Callvirt, DicStrObjGetter); }); } }
private object GenReadArray(NodeTree node) { NodeTree elem = node.Children[1]; object proto; // Try Primitive Type Type elemtype; if (PrimitiveTypeDic.TryGetValue(elem.Type, out elemtype)) { // reader.ReadValueArray<T>() var readfunc = ReadValueArray.MakeGenericMethod(elemtype); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, readfunc); proto = Activator.CreateInstance(elemtype.MakeArrayType(), new object[] { 0 }); } // Try String else if (elem.Type == "string") { // var ary = new string[reader.ReadInt()]; il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, ReadInt); il.Emit(OpCodes.Newarr, typeof(string)); int i = locman.AllocLocal(typeof(int)); // for(int i = 0; i < ary.Length; i++) il.EmitFor(i, cond: (cil) => { il.Emit(OpCodes.Dup); il.Emit(OpCodes.Ldlen); il.Emit(OpCodes.Conv_I4); il.EmitLdloc(i); return(OpCodes.Ble_S); }, block: (cil) => { // ary[i] = r.ReadAlignedString(); il.Emit(OpCodes.Dup); il.EmitLdloc(i); GenReadString(); il.Emit(OpCodes.Stelem, typeof(string)); } ); locman.ReleaseLocal(typeof(int)); proto = new string[0]; } else if (elem.Type == "map") { throw new NotImplementedException("Array of map is not supported"); } // Object else { string FQN = protoman.GetFQN(elem.Type); // vec = new DynamicAssetArray(reader.ReadInt(), protoname) il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, ReadInt); il.Emit(OpCodes.Ldstr, FQN); il.Emit(OpCodes.Newobj, DynamicAssetArrayCtor); // ary = vec.elems; il.Emit(OpCodes.Dup); il.Emit(OpCodes.Ldfld, DynamicAssetArrayelems); // for(int i = 0; i < ary.Length; i++) int i = locman.AllocLocal(typeof(int)); il.EmitFor(i, (cil) => { il.Emit(OpCodes.Dup); il.Emit(OpCodes.Ldlen); il.Emit(OpCodes.Conv_I4); il.EmitLdloc(i); return(OpCodes.Ble); }, (cil) => { // ary[i] = new DynamicAsset(GenReadUnkownType()); il.Emit(OpCodes.Dup); il.EmitLdloc(i); // Fallback GenReadUnknownType(elem, requireBoxing: false); il.Emit(OpCodes.Stelem_Ref); } ); il.Emit(OpCodes.Pop); proto = new DynamicAssetArray(0, FQN); } if (node.IsAligned) { GenAlign(); } return(proto); }