Esempio n. 1
0
            private void GenWriteUnknownType(NodeTree node, bool requireUnboxing, Action <ILGenerator> loader)
            {
                // Try Known Type
                if (TryGenKnownType(node, requireUnboxing, loader))
                {
                }
                else if (node.Type == "TypelessData")
                {
                    // Assert node.Children[0].Type == "int" && node.Children[0].Name == "size"
                    // Assert node.Children[1].Type == "UInt8" && node.Children[1].Name == "data"
                    var writefunc = WriteValueArray.MakeGenericMethod(typeof(byte));
                    il.Emit(OpCodes.Ldarg_0);
                    loader(il);
                    il.Emit(OpCodes.Castclass, typeof(byte).MakeArrayType());
                    il.Emit(OpCodes.Call, writefunc);
                }
                // Map
                else if (node.Type == "map")
                {
                    GenWriteDic(node, loader);
                }
                // Array
                else if (node.HasChildren && node.Children[0].Type == "Array")
                {
                    GenWriteArray(node.Children[0], loader);
                }
                else
                {
                    loader(il);
                    GenWriteObject(node);
                }

                if (node.IsAligned)
                {
                    GenAlign();
                }
            }
Esempio n. 2
0
            private void GenWriteArray(NodeTree node, Action <ILGenerator> loader)
            {
                NodeTree elem = node.Children[1];

                // Try Primitive Type
                Type elemtype;

                if (PrimitiveTypeDic.TryGetValue(elem.Type, out elemtype))
                {
                    // reader.ReadValueArray<T>()
                    var writefunc = WriteValueArray.MakeGenericMethod(elemtype);
                    il.Emit(OpCodes.Ldarg_0);
                    loader(il);
                    il.Emit(OpCodes.Castclass, elemtype.MakeArrayType());
                    il.Emit(OpCodes.Call, writefunc);
                }
                // Try String
                else if (elem.Type == "string")
                {
                    Type arytype = typeof(string).MakeArrayType();
                    int  ary     = locman.AllocLocal(arytype);
                    loader(il);
                    il.Emit(OpCodes.Castclass, arytype);
                    il.EmitStloc(ary);

                    // Write length
                    // writer.WriteInt(ary.Length);
                    il.Emit(OpCodes.Ldarg_0);
                    il.EmitLdloc(ary);
                    il.Emit(OpCodes.Ldlen);
                    il.Emit(OpCodes.Conv_I4);
                    il.Emit(OpCodes.Call, WriteInt);

                    int i = locman.AllocLocal(typeof(int));
                    // for(int i = 0; i < ary.Length; i++)
                    il.EmitFor(i,
                               cond: (cil) => {
                        il.EmitLdloc(ary);
                        il.Emit(OpCodes.Ldlen);
                        il.Emit(OpCodes.Conv_I4);
                        il.EmitLdloc(i);
                        return(OpCodes.Ble_S);
                    },
                               block: (cil) => {
                        // w.WriteAlignedString(ary[i]);
                        il.Emit(OpCodes.Ldarg_0);
                        il.EmitLdloc(ary);
                        il.EmitLdloc(i);
                        il.Emit(OpCodes.Ldelem_Ref);
                        il.Emit(OpCodes.Call, WriteAlignedString);
                    }
                               );
                    locman.ReleaseLocal(typeof(int));
                    locman.ReleaseLocal(arytype);
                }
                else if (elem.Type == "map")
                {
                    throw new NotImplementedException("Array of map is not supported");
                }
                // Object
                else
                {
                    // Load DynamicAssetArray.elems
                    Type arytype = typeof(IDynamicAssetBase).MakeArrayType();
                    int  ary     = locman.AllocLocal(arytype);
                    loader(il);
                    il.Emit(OpCodes.Castclass, typeof(DynamicAssetArray));
                    il.Emit(OpCodes.Ldfld, DynamicAssetArrayelems);
                    il.EmitStloc(ary);

                    // Write length
                    // writer.WriteInt(ary.Length);
                    il.Emit(OpCodes.Ldarg_0);
                    il.EmitLdloc(ary);
                    il.Emit(OpCodes.Ldlen);
                    il.Emit(OpCodes.Conv_I4);
                    il.Emit(OpCodes.Call, WriteInt);

                    // for(int i = 0; i < ary.Length; i++)
                    int i = locman.AllocLocal(typeof(int));
                    il.EmitFor(i,
                               (cil) => {
                        il.EmitLdloc(ary);
                        il.Emit(OpCodes.Ldlen);
                        il.Emit(OpCodes.Conv_I4);
                        il.EmitLdloc(i);
                        return(OpCodes.Ble);
                    },
                               (cil) => {
                        // GenWriteUnknownType(ary[i]);
                        GenWriteUnknownType(elem, requireUnboxing: false, loader: (ccil) => {
                            ccil.EmitLdloc(ary);
                            ccil.EmitLdloc(i);
                            ccil.Emit(OpCodes.Ldelem_Ref);
                        });
                    }
                               );

                    locman.ReleaseLocal(typeof(int));
                    locman.ReleaseLocal(arytype);
                }
                if (node.IsAligned)
                {
                    GenAlign();
                }
            }