private object GenReadUnknownType(NodeTree node, bool requireBoxing)
            {
                object proto;

                // Try Known Type
                if (TryGenKnownType(node, requireBoxing, out proto))
                {
                }
                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 readfunc = ReadValueArray.MakeGenericMethod(typeof(byte));
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Call, readfunc);

                    proto = new byte[0];
                }
                // Map
                else if (node.Type == "map")
                {
                    proto = GenReadDic(node);
                }
                // Array
                else if (node.HasChildren && node.Children[0].Type == "Array")
                {
                    proto = GenReadArray(node.Children[0]);
                }
                else
                {
                    proto = GenReadObject(node);
                }

                if (node.IsAligned)
                {
                    GenAlign();
                }

                return(proto);
            }
            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);
            }