Example #1
0
            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);
            }