少年修仙传客户端基础资源
client_Wu Xijin
2018-10-29 8efd04f4314e44c5b732e95163383b1911d279cb
Assets/XLua/Src/Utils.cs
@@ -24,38 +24,38 @@
namespace XLua
{
    public enum LazyMemberTypes
    {
        Method,
        FieldGet,
        FieldSet,
        PropertyGet,
        PropertySet,
        Event,
    }
   public enum LazyMemberTypes
   {
      Method,
      FieldGet,
      FieldSet,
      PropertyGet,
      PropertySet,
      Event,
   }
    public static partial class Utils
    {
        public static bool LoadField(RealStatePtr L, int idx, string field_name)
        {
            idx = idx > 0 ? idx : LuaAPI.lua_gettop(L) + idx + 1;// abs of index
            LuaAPI.xlua_pushasciistring(L, field_name);
            LuaAPI.lua_rawget(L, idx);
            return !LuaAPI.lua_isnil(L, -1);
        }
   public static partial class Utils
   {
      public static bool LoadField(RealStatePtr L, int idx, string field_name)
      {
         idx = idx > 0 ? idx : LuaAPI.lua_gettop(L) + idx + 1;// abs of index
         LuaAPI.xlua_pushasciistring(L, field_name);
         LuaAPI.lua_rawget(L, idx);
         return !LuaAPI.lua_isnil(L, -1);
      }
        public static RealStatePtr GetMainState(RealStatePtr L)
        {
            RealStatePtr ret = default(RealStatePtr);
            LuaAPI.xlua_pushasciistring(L, "xlua_main_thread");
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            if (LuaAPI.lua_isthread(L, -1))
            {
                ret = LuaAPI.lua_tothread(L, -1);
            }
            LuaAPI.lua_pop(L, 1);
            return ret;
        }
      public static RealStatePtr GetMainState(RealStatePtr L)
      {
         RealStatePtr ret = default(RealStatePtr);
         LuaAPI.xlua_pushasciistring(L, "xlua_main_thread");
         LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
         if (LuaAPI.lua_isthread(L, -1))
         {
            ret = LuaAPI.lua_tothread(L, -1);
         }
         LuaAPI.lua_pop(L, 1);
         return ret;
      }
#if (UNITY_WSA && !ENABLE_IL2CPP) && !UNITY_EDITOR
        public static List<Assembly> _assemblies;
@@ -105,1039 +105,1043 @@
                   select type;
        }
#else
        public static List<Type> GetAllTypes(bool exclude_generic_definition = true)
        {
            List<Type> allTypes = new List<Type>();
            var assemblies = AppDomain.CurrentDomain.GetAssemblies();
            for(int i = 0; i < assemblies.Length; i++)
            {
                try
                {
      public static List<Type> GetAllTypes(bool exclude_generic_definition = true)
      {
         List<Type> allTypes = new List<Type>();
         var assemblies = AppDomain.CurrentDomain.GetAssemblies();
         for (int i = 0; i < assemblies.Length; i++)
         {
            try
            {
#if UNITY_EDITOR || XLUA_GENERAL
                    if (!(assemblies[i].ManifestModule is System.Reflection.Emit.ModuleBuilder))
                    {
               if (!(assemblies[i].ManifestModule is System.Reflection.Emit.ModuleBuilder))
               {
#endif
                        allTypes.AddRange(assemblies[i].GetTypes()
                        .Where(type => exclude_generic_definition ? !type.IsGenericTypeDefinition() : true)
                        );
                  allTypes.AddRange(assemblies[i].GetTypes()
                  .Where(type => exclude_generic_definition ? !type.IsGenericTypeDefinition() : true)
                  );
#if UNITY_EDITOR || XLUA_GENERAL
                    }
               }
#endif
                }
                catch (Exception)
                {
                }
            }
            }
            catch (Exception)
            {
            }
         }
            return allTypes;
        }
         return allTypes;
      }
#endif
        static LuaCSFunction genFieldGetter(Type type, FieldInfo field)
        {
            if (field.IsStatic)
            {
                return (RealStatePtr L) =>
                {
                    ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
                    translator.PushAny(L, field.GetValue(null));
                    return 1;
                };
            }
            else
            {
                return (RealStatePtr L) =>
                {
                    ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
                    object obj = translator.FastGetCSObj(L, 1);
                    if (obj == null || !type.IsInstanceOfType(obj))
                    {
                        return LuaAPI.luaL_error(L, "Expected type " + type + ", but got " + (obj == null ? "null" : obj.GetType().ToString()) + ", while get field " + field);
                    }
      static LuaCSFunction genFieldGetter(Type type, FieldInfo field)
      {
         if (field.IsStatic)
         {
            return (RealStatePtr L) =>
            {
               ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
               translator.PushAny(L, field.GetValue(null));
               return 1;
            };
         }
         else
         {
            return (RealStatePtr L) =>
            {
               ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
               object obj = translator.FastGetCSObj(L, 1);
               if (obj == null || !type.IsInstanceOfType(obj))
               {
                  return LuaAPI.luaL_error(L, "Expected type " + type + ", but got " + (obj == null ? "null" : obj.GetType().ToString()) + ", while get field " + field);
               }
                    translator.PushAny(L, field.GetValue(obj));
                    return 1;
                };
            }
        }
               translator.PushAny(L, field.GetValue(obj));
               return 1;
            };
         }
      }
        static LuaCSFunction genFieldSetter(Type type, FieldInfo field)
        {
            if (field.IsStatic)
            {
                return (RealStatePtr L) =>
                {
                    ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
                    object val = translator.GetObject(L, 1, field.FieldType);
                    if (field.FieldType.IsValueType() && Nullable.GetUnderlyingType(field.FieldType) == null && val == null)
                    {
                        return LuaAPI.luaL_error(L, type.Name + "." + field.Name + " Expected type " + field.FieldType);
                    }
                    field.SetValue(null, val);
                    return 0;
                };
            }
            else
            {
                return (RealStatePtr L) =>
                {
                    ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
      static LuaCSFunction genFieldSetter(Type type, FieldInfo field)
      {
         if (field.IsStatic)
         {
            return (RealStatePtr L) =>
            {
               ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
               object val = translator.GetObject(L, 1, field.FieldType);
               if (field.FieldType.IsValueType() && Nullable.GetUnderlyingType(field.FieldType) == null && val == null)
               {
                  return LuaAPI.luaL_error(L, type.Name + "." + field.Name + " Expected type " + field.FieldType);
               }
               field.SetValue(null, val);
               return 0;
            };
         }
         else
         {
            return (RealStatePtr L) =>
            {
               ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
                    object obj = translator.FastGetCSObj(L, 1);
                    if (obj == null || !type.IsInstanceOfType(obj))
                    {
                        return LuaAPI.luaL_error(L, "Expected type " + type + ", but got " + (obj == null ? "null" : obj.GetType().ToString()) + ", while set field " + field);
                    }
               object obj = translator.FastGetCSObj(L, 1);
               if (obj == null || !type.IsInstanceOfType(obj))
               {
                  return LuaAPI.luaL_error(L, "Expected type " + type + ", but got " + (obj == null ? "null" : obj.GetType().ToString()) + ", while set field " + field);
               }
                    object val = translator.GetObject(L, 2, field.FieldType);
                    if (field.FieldType.IsValueType() && Nullable.GetUnderlyingType(field.FieldType) == null && val == null)
                    {
                        return LuaAPI.luaL_error(L, type.Name + "." + field.Name + " Expected type " + field.FieldType);
                    }
                    field.SetValue(obj, val);
                    if (type.IsValueType)
                    {
                        translator.Update(L, 1, obj);
                    }
                    return 0;
                };
            }
        }
               object val = translator.GetObject(L, 2, field.FieldType);
               if (field.FieldType.IsValueType() && Nullable.GetUnderlyingType(field.FieldType) == null && val == null)
               {
                  return LuaAPI.luaL_error(L, type.Name + "." + field.Name + " Expected type " + field.FieldType);
               }
               field.SetValue(obj, val);
               if (type.IsValueType)
               {
                  translator.Update(L, 1, obj);
               }
               return 0;
            };
         }
      }
        static LuaCSFunction genItemGetter(Type type, PropertyInfo[] props)
        {
            props = props.Where(prop => !prop.GetIndexParameters()[0].ParameterType.IsAssignableFrom(typeof(string))).ToArray();
            if (props.Length == 0)
            {
                return null;
            }
            Type[] params_type = new Type[props.Length];
            for(int i = 0; i < props.Length; i++)
            {
                params_type[i] = props[i].GetIndexParameters()[0].ParameterType;
            }
            object[] arg = new object[1] { null };
            return (RealStatePtr L) =>
            {
                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
                object obj = translator.FastGetCSObj(L, 1);
                if (obj == null || !type.IsInstanceOfType(obj))
                {
                    return LuaAPI.luaL_error(L, "Expected type " + type + ", but got " + (obj == null ? "null" : obj.GetType().ToString()) + ", while get prop " + props[0].Name);
                }
      static LuaCSFunction genItemGetter(Type type, PropertyInfo[] props)
      {
         props = props.Where(prop => !prop.GetIndexParameters()[0].ParameterType.IsAssignableFrom(typeof(string))).ToArray();
         if (props.Length == 0)
         {
            return null;
         }
         Type[] params_type = new Type[props.Length];
         for (int i = 0; i < props.Length; i++)
         {
            params_type[i] = props[i].GetIndexParameters()[0].ParameterType;
         }
         object[] arg = new object[1] { null };
         return (RealStatePtr L) =>
         {
            ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
            object obj = translator.FastGetCSObj(L, 1);
            if (obj == null || !type.IsInstanceOfType(obj))
            {
               return LuaAPI.luaL_error(L, "Expected type " + type + ", but got " + (obj == null ? "null" : obj.GetType().ToString()) + ", while get prop " + props[0].Name);
            }
                for (int i = 0; i < props.Length; i++)
                {
                    if (!translator.Assignable(L, 2, params_type[i]))
                    {
                        continue;
                    }
                    else
                    {
                        PropertyInfo prop = props[i];
                        try
                        {
                            object index = translator.GetObject(L, 2, params_type[i]);
                            arg[0] = index;
                            object ret = prop.GetValue(obj, arg);
                            LuaAPI.lua_pushboolean(L, true);
                            translator.PushAny(L, ret);
                            return 2;
                        }
                        catch (Exception e)
                        {
                            return LuaAPI.luaL_error(L, "try to get " + type + "." + prop.Name + " throw a exception:" + e + ",stack:" + e.StackTrace);
                        }
                    }
                }
            for (int i = 0; i < props.Length; i++)
            {
               if (!translator.Assignable(L, 2, params_type[i]))
               {
                  continue;
               }
               else
               {
                  PropertyInfo prop = props[i];
                  try
                  {
                     object index = translator.GetObject(L, 2, params_type[i]);
                     arg[0] = index;
                     object ret = prop.GetValue(obj, arg);
                     LuaAPI.lua_pushboolean(L, true);
                     translator.PushAny(L, ret);
                     return 2;
                  }
                  catch (Exception e)
                  {
                     return LuaAPI.luaL_error(L, "try to get " + type + "." + prop.Name + " throw a exception:" + e + ",stack:" + e.StackTrace);
                  }
               }
            }
                LuaAPI.lua_pushboolean(L, false);
                return 1;
            };
        }
            LuaAPI.lua_pushboolean(L, false);
            return 1;
         };
      }
        static LuaCSFunction genItemSetter(Type type, PropertyInfo[] props)
        {
            props = props.Where(prop => !prop.GetIndexParameters()[0].ParameterType.IsAssignableFrom(typeof(string))).ToArray();
            if (props.Length == 0)
            {
                return null;
            }
            Type[] params_type = new Type[props.Length];
            for (int i = 0; i < props.Length; i++)
            {
                params_type[i] = props[i].GetIndexParameters()[0].ParameterType;
            }
            object[] arg = new object[1] { null };
            return (RealStatePtr L) =>
            {
                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
                object obj = translator.FastGetCSObj(L, 1);
                if (obj == null || !type.IsInstanceOfType(obj))
                {
                    return LuaAPI.luaL_error(L, "Expected type " + type + ", but got " + (obj == null ? "null" : obj.GetType().ToString()) + ", while set prop " + props[0].Name);
                }
      static LuaCSFunction genItemSetter(Type type, PropertyInfo[] props)
      {
         props = props.Where(prop => !prop.GetIndexParameters()[0].ParameterType.IsAssignableFrom(typeof(string))).ToArray();
         if (props.Length == 0)
         {
            return null;
         }
         Type[] params_type = new Type[props.Length];
         for (int i = 0; i < props.Length; i++)
         {
            params_type[i] = props[i].GetIndexParameters()[0].ParameterType;
         }
         object[] arg = new object[1] { null };
         return (RealStatePtr L) =>
         {
            ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
            object obj = translator.FastGetCSObj(L, 1);
            if (obj == null || !type.IsInstanceOfType(obj))
            {
               return LuaAPI.luaL_error(L, "Expected type " + type + ", but got " + (obj == null ? "null" : obj.GetType().ToString()) + ", while set prop " + props[0].Name);
            }
                for (int i = 0; i < props.Length; i++)
                {
                    if (!translator.Assignable(L, 2, params_type[i]))
                    {
                        continue;
                    }
                    else
                    {
                        PropertyInfo prop = props[i];
                        try
                        {
                            arg[0] = translator.GetObject(L, 2, params_type[i]);
                            object val = translator.GetObject(L, 3, prop.PropertyType);
                            if (val == null)
                            {
                                return LuaAPI.luaL_error(L, type.Name + "." + prop.Name + " Expected type " + prop.PropertyType);
                            }
                            prop.SetValue(obj, val, arg);
                            LuaAPI.lua_pushboolean(L, true);
                            return 1;
                        }
                        catch (Exception e)
                        {
                            return LuaAPI.luaL_error(L, "try to set " + type + "." + prop.Name + " throw a exception:" + e + ",stack:" + e.StackTrace);
                        }
                    }
                }
            for (int i = 0; i < props.Length; i++)
            {
               if (!translator.Assignable(L, 2, params_type[i]))
               {
                  continue;
               }
               else
               {
                  PropertyInfo prop = props[i];
                  try
                  {
                     arg[0] = translator.GetObject(L, 2, params_type[i]);
                     object val = translator.GetObject(L, 3, prop.PropertyType);
                     if (val == null)
                     {
                        return LuaAPI.luaL_error(L, type.Name + "." + prop.Name + " Expected type " + prop.PropertyType);
                     }
                     prop.SetValue(obj, val, arg);
                     LuaAPI.lua_pushboolean(L, true);
                LuaAPI.lua_pushboolean(L, false);
                return 1;
            };
        }
                     return 1;
                  }
                  catch (Exception e)
                  {
                     return LuaAPI.luaL_error(L, "try to set " + type + "." + prop.Name + " throw a exception:" + e + ",stack:" + e.StackTrace);
                  }
               }
            }
        static LuaCSFunction genEnumCastFrom(Type type)
        {
            return (RealStatePtr L) =>
            {
                try
                {
                    ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
                    return translator.TranslateToEnumToTop(L, type, 1);
                }
                catch(Exception e)
                {
                    return LuaAPI.luaL_error(L, "cast to " + type + " exception:" + e);
                }
            };
        }
            LuaAPI.lua_pushboolean(L, false);
            return 1;
         };
      }
        internal static IEnumerable<MethodInfo> GetExtensionMethodsOf(Type type_to_be_extend)
        {
            if (InternalGlobals.extensionMethodMap == null)
            {
                List<Type> type_def_extention_method = new List<Type>();
      static LuaCSFunction genEnumCastFrom(Type type)
      {
         return (RealStatePtr L) =>
         {
            try
            {
               ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
               return translator.TranslateToEnumToTop(L, type, 1);
            }
            catch (Exception e)
            {
               return LuaAPI.luaL_error(L, "cast to " + type + " exception:" + e);
            }
         };
      }
                IEnumerator<Type> enumerator = GetAllTypes().GetEnumerator();
                while(enumerator.MoveNext())
                {
                    Type type = enumerator.Current;
                    if (type.IsDefined(typeof(ExtensionAttribute), false)  && (
                            type.IsDefined(typeof(ReflectionUseAttribute), false)
      internal static IEnumerable<MethodInfo> GetExtensionMethodsOf(Type type_to_be_extend)
      {
         if (InternalGlobals.extensionMethodMap == null)
         {
            List<Type> type_def_extention_method = new List<Type>();
            IEnumerator<Type> enumerator = GetAllTypes().GetEnumerator();
            while (enumerator.MoveNext())
            {
               Type type = enumerator.Current;
               if (type.IsDefined(typeof(ExtensionAttribute), false) && (
                     type.IsDefined(typeof(ReflectionUseAttribute), false)
#if UNITY_EDITOR || XLUA_GENERAL
                            || type.IsDefined(typeof(LuaCallCSharpAttribute), false)
                     || type.IsDefined(typeof(LuaCallCSharpAttribute), false)
#endif
                        ))
                    {
                        type_def_extention_method.Add(type);
                    }
                  ))
               {
                  type_def_extention_method.Add(type);
               }
                    if (!type.IsAbstract() || !type.IsSealed()) continue;
               if (!type.IsAbstract() || !type.IsSealed()) continue;
                    var fields = type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
                    for (int i = 0; i < fields.Length; i++)
                    {
                        var field = fields[i];
                        if ((field.IsDefined(typeof(ReflectionUseAttribute), false)
               var fields = type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
               for (int i = 0; i < fields.Length; i++)
               {
                  var field = fields[i];
                  if ((field.IsDefined(typeof(ReflectionUseAttribute), false)
#if UNITY_EDITOR || XLUA_GENERAL
                            || field.IsDefined(typeof(LuaCallCSharpAttribute), false)
                     || field.IsDefined(typeof(LuaCallCSharpAttribute), false)
#endif
                            ) && (typeof(IEnumerable<Type>)).IsAssignableFrom(field.FieldType))
                        {
                            type_def_extention_method.AddRange((field.GetValue(null) as IEnumerable<Type>)
                                .Where(t => t.IsDefined(typeof(ExtensionAttribute), false)));
                        }
                    }
                     ) && (typeof(IEnumerable<Type>)).IsAssignableFrom(field.FieldType))
                  {
                     type_def_extention_method.AddRange((field.GetValue(null) as IEnumerable<Type>)
                        .Where(t => t.IsDefined(typeof(ExtensionAttribute), false)));
                  }
               }
                    var props = type.GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
                    for (int i = 0; i < props.Length; i++)
                    {
                        var prop = props[i];
                        if ((prop.IsDefined(typeof(ReflectionUseAttribute), false)
               var props = type.GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
               for (int i = 0; i < props.Length; i++)
               {
                  var prop = props[i];
                  if ((prop.IsDefined(typeof(ReflectionUseAttribute), false)
#if UNITY_EDITOR || XLUA_GENERAL
                            || prop.IsDefined(typeof(LuaCallCSharpAttribute), false)
                     || prop.IsDefined(typeof(LuaCallCSharpAttribute), false)
#endif
                            ) && (typeof(IEnumerable<Type>)).IsAssignableFrom(prop.PropertyType))
                        {
                            type_def_extention_method.AddRange((prop.GetValue(null, null) as IEnumerable<Type>)
                                .Where(t => t.IsDefined(typeof(ExtensionAttribute), false)));
                        }
                    }
                }
                enumerator.Dispose();
                     ) && (typeof(IEnumerable<Type>)).IsAssignableFrom(prop.PropertyType))
                  {
                     type_def_extention_method.AddRange((prop.GetValue(null, null) as IEnumerable<Type>)
                        .Where(t => t.IsDefined(typeof(ExtensionAttribute), false)));
                  }
               }
            }
            enumerator.Dispose();
                InternalGlobals.extensionMethodMap = (from type in type_def_extention_method
                                        from method in type.GetMethods(BindingFlags.Static | BindingFlags.Public)
                                        where method.IsDefined(typeof(ExtensionAttribute), false) && IsSupportedMethod(method)
                                        group method by getExtendedType(method)).ToDictionary(g => g.Key, g => g as IEnumerable<MethodInfo>);
            }
            IEnumerable<MethodInfo> ret = null;
            InternalGlobals.extensionMethodMap.TryGetValue(type_to_be_extend, out ret);
            return ret;
        }
            InternalGlobals.extensionMethodMap = (from type in type_def_extention_method
                                         from method in type.GetMethods(BindingFlags.Static | BindingFlags.Public)
                                         where method.IsDefined(typeof(ExtensionAttribute), false) && IsSupportedMethod(method)
                                         group method by getExtendedType(method)).ToDictionary(g => g.Key, g => g as IEnumerable<MethodInfo>);
         }
         IEnumerable<MethodInfo> ret = null;
         InternalGlobals.extensionMethodMap.TryGetValue(type_to_be_extend, out ret);
         return ret;
      }
        struct MethodKey
        {
            public string Name;
            public bool IsStatic;
        }
      struct MethodKey
      {
         public string Name;
         public bool IsStatic;
      }
        static void makeReflectionWrap(RealStatePtr L, Type type, int cls_field, int cls_getter, int cls_setter,
            int obj_field, int obj_getter, int obj_setter, int obj_meta, out LuaCSFunction item_getter, out LuaCSFunction item_setter, BindingFlags access)
        {
            ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
            BindingFlags flag = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | access;
            FieldInfo[] fields = type.GetFields(flag);
            EventInfo[] all_events = type.GetEvents(flag | BindingFlags.Public | BindingFlags.NonPublic);
      static void makeReflectionWrap(RealStatePtr L, Type type, int cls_field, int cls_getter, int cls_setter,
         int obj_field, int obj_getter, int obj_setter, int obj_meta, out LuaCSFunction item_getter, out LuaCSFunction item_setter, BindingFlags access)
      {
         ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
         BindingFlags flag = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | access;
         FieldInfo[] fields = type.GetFields(flag);
         EventInfo[] all_events = type.GetEvents(flag | BindingFlags.Public | BindingFlags.NonPublic);
            for (int i = 0; i < fields.Length; ++i)
            {
                FieldInfo field = fields[i];
                string fieldName = field.Name;
                // skip hotfix inject field
                if (field.IsStatic && (field.Name.StartsWith("__Hotfix") || field.Name.StartsWith("_c__Hotfix")) && typeof(Delegate).IsAssignableFrom(field.FieldType))
                {
                    continue;
                }
                if (all_events.Any(e => e.Name == fieldName))
                {
                    fieldName = "&" + fieldName;
                }
         for (int i = 0; i < fields.Length; ++i)
         {
            FieldInfo field = fields[i];
            string fieldName = field.Name;
            // skip hotfix inject field
            if (field.IsStatic && (field.Name.StartsWith("__Hotfix") || field.Name.StartsWith("_c__Hotfix")) && typeof(Delegate).IsAssignableFrom(field.FieldType))
            {
               continue;
            }
            if (all_events.Any(e => e.Name == fieldName))
            {
               fieldName = "&" + fieldName;
            }
                if (field.IsStatic && (field.IsInitOnly || field.IsLiteral))
                {
                    LuaAPI.xlua_pushasciistring(L, fieldName);
                    translator.PushAny(L, field.GetValue(null));
                    LuaAPI.lua_rawset(L, cls_field);
                }
                else
                {
                    LuaAPI.xlua_pushasciistring(L, fieldName);
                    translator.PushFixCSFunction(L, genFieldGetter(type, field));
                    LuaAPI.lua_rawset(L, field.IsStatic ? cls_getter : obj_getter);
            if (field.IsStatic && (field.IsInitOnly || field.IsLiteral))
            {
               LuaAPI.xlua_pushasciistring(L, fieldName);
               translator.PushAny(L, field.GetValue(null));
               LuaAPI.lua_rawset(L, cls_field);
            }
            else
            {
               LuaAPI.xlua_pushasciistring(L, fieldName);
               translator.PushFixCSFunction(L, genFieldGetter(type, field));
               LuaAPI.lua_rawset(L, field.IsStatic ? cls_getter : obj_getter);
                    LuaAPI.xlua_pushasciistring(L, fieldName);
                    translator.PushFixCSFunction(L, genFieldSetter(type, field));
                    LuaAPI.lua_rawset(L, field.IsStatic ? cls_setter : obj_setter);
                }
            }
               LuaAPI.xlua_pushasciistring(L, fieldName);
               translator.PushFixCSFunction(L, genFieldSetter(type, field));
               LuaAPI.lua_rawset(L, field.IsStatic ? cls_setter : obj_setter);
            }
         }
            EventInfo[] events = type.GetEvents(flag);
            for (int i = 0; i < events.Length; ++i)
            {
                EventInfo eventInfo = events[i];
                LuaAPI.xlua_pushasciistring(L, eventInfo.Name);
                translator.PushFixCSFunction(L, translator.methodWrapsCache.GetEventWrap(type, eventInfo.Name));
                bool is_static = (eventInfo.GetAddMethod(true) != null) ? eventInfo.GetAddMethod(true).IsStatic : eventInfo.GetRemoveMethod(true).IsStatic;
                LuaAPI.lua_rawset(L, is_static ? cls_field : obj_field);
            }
         EventInfo[] events = type.GetEvents(flag);
         for (int i = 0; i < events.Length; ++i)
         {
            EventInfo eventInfo = events[i];
            LuaAPI.xlua_pushasciistring(L, eventInfo.Name);
            translator.PushFixCSFunction(L, translator.methodWrapsCache.GetEventWrap(type, eventInfo.Name));
            bool is_static = (eventInfo.GetAddMethod(true) != null) ? eventInfo.GetAddMethod(true).IsStatic : eventInfo.GetRemoveMethod(true).IsStatic;
            LuaAPI.lua_rawset(L, is_static ? cls_field : obj_field);
         }
            List<PropertyInfo> items = new List<PropertyInfo>();
            PropertyInfo[] props = type.GetProperties(flag);
            for (int i = 0; i < props.Length; ++i)
            {
                PropertyInfo prop = props[i];
                if (prop.Name == "Item" && prop.GetIndexParameters().Length > 0)
                {
                    items.Add(prop);
                }
            }
         List<PropertyInfo> items = new List<PropertyInfo>();
         PropertyInfo[] props = type.GetProperties(flag);
         for (int i = 0; i < props.Length; ++i)
         {
            PropertyInfo prop = props[i];
            if (prop.GetIndexParameters().Length > 0)
            {
               items.Add(prop);
            }
         }
            var item_array = items.ToArray();
            item_getter = item_array.Length > 0 ? genItemGetter(type, item_array) : null;
            item_setter = item_array.Length > 0 ? genItemSetter(type, item_array) : null; ;
            MethodInfo[] methods = type.GetMethods(flag);
            Dictionary<MethodKey, List<MemberInfo>> pending_methods = new Dictionary<MethodKey, List<MemberInfo>>();
            for (int i = 0; i < methods.Length; ++i)
            {
                MethodInfo method = methods[i];
                string method_name = method.Name;
         var item_array = items.ToArray();
         item_getter = item_array.Length > 0 ? genItemGetter(type, item_array) : null;
         item_setter = item_array.Length > 0 ? genItemSetter(type, item_array) : null;
         MethodInfo[] methods = type.GetMethods(flag);
         if (access == BindingFlags.NonPublic)
         {
            methods = type.GetMethods(flag | BindingFlags.Public).Join(methods, p => p.Name, q => q.Name, (p, q) => p).ToArray();
         }
         Dictionary<MethodKey, List<MemberInfo>> pending_methods = new Dictionary<MethodKey, List<MemberInfo>>();
         for (int i = 0; i < methods.Length; ++i)
         {
            MethodInfo method = methods[i];
            string method_name = method.Name;
                MethodKey method_key = new MethodKey { Name = method_name, IsStatic = method.IsStatic };
                List<MemberInfo> overloads;
                if (pending_methods.TryGetValue(method_key, out overloads))
                {
                    overloads.Add(method);
                    continue;
                }
            MethodKey method_key = new MethodKey { Name = method_name, IsStatic = method.IsStatic };
            List<MemberInfo> overloads;
            if (pending_methods.TryGetValue(method_key, out overloads))
            {
               overloads.Add(method);
               continue;
            }
                //indexer
                if (method.IsSpecialName && ((method.Name == "get_Item" && method.GetParameters().Length == 1) || (method.Name == "set_Item" && method.GetParameters().Length == 2)))
                {
                    if (!method.GetParameters()[0].ParameterType.IsAssignableFrom(typeof(string)))
                    {
                        continue;
                    }
                }
            //indexer
            if (method.IsSpecialName && ((method.Name == "get_Item" && method.GetParameters().Length == 1) || (method.Name == "set_Item" && method.GetParameters().Length == 2)))
            {
               if (!method.GetParameters()[0].ParameterType.IsAssignableFrom(typeof(string)))
               {
                  continue;
               }
            }
                if ((method_name.StartsWith("add_") || method_name.StartsWith("remove_")) && method.IsSpecialName)
                {
                    continue;
                }
            if ((method_name.StartsWith("add_") || method_name.StartsWith("remove_")) && method.IsSpecialName)
            {
               continue;
            }
                if (method_name.StartsWith("op_") && method.IsSpecialName) // 操作符
                {
                    if (InternalGlobals.supportOp.ContainsKey(method_name))
                    {
                        if (overloads == null)
                        {
                            overloads = new List<MemberInfo>();
                            pending_methods.Add(method_key, overloads);
                        }
                        overloads.Add(method);
                    }
                    continue;
                }
                else if (method_name.StartsWith("get_") && method.IsSpecialName && method.GetParameters().Length != 1) // getter of property
                {
                    string prop_name = method.Name.Substring(4);
                    LuaAPI.xlua_pushasciistring(L, prop_name);
                    translator.PushFixCSFunction(L, translator.methodWrapsCache._GenMethodWrap(method.DeclaringType, prop_name, new MethodBase[] { method }).Call);
                    LuaAPI.lua_rawset(L, method.IsStatic ? cls_getter : obj_getter);
                }
                else if (method_name.StartsWith("set_") && method.IsSpecialName && method.GetParameters().Length != 2) // setter of property
                {
                    string prop_name = method.Name.Substring(4);
                    LuaAPI.xlua_pushasciistring(L, prop_name);
                    translator.PushFixCSFunction(L, translator.methodWrapsCache._GenMethodWrap(method.DeclaringType, prop_name, new MethodBase[] { method }).Call);
                    LuaAPI.lua_rawset(L, method.IsStatic ? cls_setter : obj_setter);
                }
                else if (method_name == ".ctor" && method.IsConstructor)
                {
                    continue;
                }
                else
                {
                    if (overloads == null)
                    {
                        overloads = new List<MemberInfo>();
                        pending_methods.Add(method_key, overloads);
                    }
                    overloads.Add(method);
                }
            }
            if (method_name.StartsWith("op_") && method.IsSpecialName) // 操作符
            {
               if (InternalGlobals.supportOp.ContainsKey(method_name))
               {
                  if (overloads == null)
                  {
                     overloads = new List<MemberInfo>();
                     pending_methods.Add(method_key, overloads);
                  }
                  overloads.Add(method);
               }
               continue;
            }
            else if (method_name.StartsWith("get_") && method.IsSpecialName && method.GetParameters().Length != 1) // getter of property
            {
               string prop_name = method.Name.Substring(4);
               LuaAPI.xlua_pushasciistring(L, prop_name);
               translator.PushFixCSFunction(L, translator.methodWrapsCache._GenMethodWrap(method.DeclaringType, prop_name, new MethodBase[] { method }).Call);
               LuaAPI.lua_rawset(L, method.IsStatic ? cls_getter : obj_getter);
            }
            else if (method_name.StartsWith("set_") && method.IsSpecialName && method.GetParameters().Length != 2) // setter of property
            {
               string prop_name = method.Name.Substring(4);
               LuaAPI.xlua_pushasciistring(L, prop_name);
               translator.PushFixCSFunction(L, translator.methodWrapsCache._GenMethodWrap(method.DeclaringType, prop_name, new MethodBase[] { method }).Call);
               LuaAPI.lua_rawset(L, method.IsStatic ? cls_setter : obj_setter);
            }
            else if (method_name == ".ctor" && method.IsConstructor)
            {
               continue;
            }
            else
            {
               if (overloads == null)
               {
                  overloads = new List<MemberInfo>();
                  pending_methods.Add(method_key, overloads);
               }
               overloads.Add(method);
            }
         }
            IEnumerable<MethodInfo> extend_methods = GetExtensionMethodsOf(type);
            if (extend_methods != null)
            {
                foreach (var extend_method in extend_methods)
                {
                    MethodKey method_key = new MethodKey { Name = extend_method.Name, IsStatic = false };
                    List<MemberInfo> overloads;
                    if (pending_methods.TryGetValue(method_key, out overloads))
                    {
                        overloads.Add(extend_method);
                        continue;
                    }
                    else
                    {
                        overloads = new List<MemberInfo>() { extend_method };
                        pending_methods.Add(method_key, overloads);
                    }
                }
            }
         IEnumerable<MethodInfo> extend_methods = GetExtensionMethodsOf(type);
         if (extend_methods != null)
         {
            foreach (var extend_method in extend_methods)
            {
               MethodKey method_key = new MethodKey { Name = extend_method.Name, IsStatic = false };
               List<MemberInfo> overloads;
               if (pending_methods.TryGetValue(method_key, out overloads))
               {
                  overloads.Add(extend_method);
                  continue;
               }
               else
               {
                  overloads = new List<MemberInfo>() { extend_method };
                  pending_methods.Add(method_key, overloads);
               }
            }
         }
            foreach (var kv in pending_methods)
            {
                if (kv.Key.Name.StartsWith("op_")) // 操作符
                {
                    LuaAPI.xlua_pushasciistring(L, InternalGlobals.supportOp[kv.Key.Name]);
                    translator.PushFixCSFunction(L,
                        new LuaCSFunction(translator.methodWrapsCache._GenMethodWrap(type, kv.Key.Name, kv.Value.ToArray()).Call));
                    LuaAPI.lua_rawset(L, obj_meta);
                }
                else
                {
                    LuaAPI.xlua_pushasciistring(L, kv.Key.Name);
                    translator.PushFixCSFunction(L,
                        new LuaCSFunction(translator.methodWrapsCache._GenMethodWrap(type, kv.Key.Name, kv.Value.ToArray()).Call));
                    LuaAPI.lua_rawset(L, kv.Key.IsStatic ? cls_field : obj_field);
                }
            }
        }
         foreach (var kv in pending_methods)
         {
            if (kv.Key.Name.StartsWith("op_")) // 操作符
            {
               LuaAPI.xlua_pushasciistring(L, InternalGlobals.supportOp[kv.Key.Name]);
               translator.PushFixCSFunction(L,
                  new LuaCSFunction(translator.methodWrapsCache._GenMethodWrap(type, kv.Key.Name, kv.Value.ToArray()).Call));
               LuaAPI.lua_rawset(L, obj_meta);
            }
            else
            {
               LuaAPI.xlua_pushasciistring(L, kv.Key.Name);
               translator.PushFixCSFunction(L,
                  new LuaCSFunction(translator.methodWrapsCache._GenMethodWrap(type, kv.Key.Name, kv.Value.ToArray()).Call));
               LuaAPI.lua_rawset(L, kv.Key.IsStatic ? cls_field : obj_field);
            }
         }
      }
        public static void loadUpvalue(RealStatePtr L, Type type, string metafunc, int num)
        {
            ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
            LuaAPI.xlua_pushasciistring(L, metafunc);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            translator.Push(L, type);
            LuaAPI.lua_rawget(L, -2);
            for (int i = 1; i <= num; i++)
            {
                LuaAPI.lua_getupvalue(L, -i, i);
                if (LuaAPI.lua_isnil(L, -1))
                {
                    LuaAPI.lua_pop(L, 1);
                    LuaAPI.lua_newtable(L);
                    LuaAPI.lua_pushvalue(L, -1);
                    LuaAPI.lua_setupvalue(L, -i - 2, i);
                }
            }
            for (int i = 0; i < num; i++)
            {
                LuaAPI.lua_remove(L, -num - 1);
            }
        }
      public static void loadUpvalue(RealStatePtr L, Type type, string metafunc, int num)
      {
         ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
         LuaAPI.xlua_pushasciistring(L, metafunc);
         LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
         translator.Push(L, type);
         LuaAPI.lua_rawget(L, -2);
         for (int i = 1; i <= num; i++)
         {
            LuaAPI.lua_getupvalue(L, -i, i);
            if (LuaAPI.lua_isnil(L, -1))
            {
               LuaAPI.lua_pop(L, 1);
               LuaAPI.lua_newtable(L);
               LuaAPI.lua_pushvalue(L, -1);
               LuaAPI.lua_setupvalue(L, -i - 2, i);
            }
         }
         for (int i = 0; i < num; i++)
         {
            LuaAPI.lua_remove(L, -num - 1);
         }
      }
        public static void MakePrivateAccessible(RealStatePtr L, Type type)
        {
            int oldTop = LuaAPI.lua_gettop(L);
      public static void MakePrivateAccessible(RealStatePtr L, Type type)
      {
         int oldTop = LuaAPI.lua_gettop(L);
            LuaAPI.luaL_getmetatable(L, type.FullName);
            if (LuaAPI.lua_isnil(L, -1))
            {
                LuaAPI.lua_settop(L, oldTop);
                throw new Exception("can not find the metatable for " + type);
            }
            int obj_meta = LuaAPI.lua_gettop(L);
         LuaAPI.luaL_getmetatable(L, type.FullName);
         if (LuaAPI.lua_isnil(L, -1))
         {
            LuaAPI.lua_settop(L, oldTop);
            throw new Exception("can not find the metatable for " + type);
         }
         int obj_meta = LuaAPI.lua_gettop(L);
            LoadCSTable(L, type);
            if (LuaAPI.lua_isnil(L, -1))
            {
                LuaAPI.lua_settop(L, oldTop);
                throw new Exception("can not find the class for " + type);
            }
            int cls_field = LuaAPI.lua_gettop(L);
         LoadCSTable(L, type);
         if (LuaAPI.lua_isnil(L, -1))
         {
            LuaAPI.lua_settop(L, oldTop);
            throw new Exception("can not find the class for " + type);
         }
         int cls_field = LuaAPI.lua_gettop(L);
            loadUpvalue(L, type, LuaIndexsFieldName, 2);
            int obj_getter = LuaAPI.lua_gettop(L);
            int obj_field = obj_getter - 1;
         loadUpvalue(L, type, LuaIndexsFieldName, 2);
         int obj_getter = LuaAPI.lua_gettop(L);
         int obj_field = obj_getter - 1;
            loadUpvalue(L, type, LuaNewIndexsFieldName, 1);
            int obj_setter = LuaAPI.lua_gettop(L);
         loadUpvalue(L, type, LuaNewIndexsFieldName, 1);
         int obj_setter = LuaAPI.lua_gettop(L);
            loadUpvalue(L, type, LuaClassIndexsFieldName, 1);
            int cls_getter = LuaAPI.lua_gettop(L);
         loadUpvalue(L, type, LuaClassIndexsFieldName, 1);
         int cls_getter = LuaAPI.lua_gettop(L);
            loadUpvalue(L, type, LuaClassNewIndexsFieldName, 1);
            int cls_setter = LuaAPI.lua_gettop(L);
         loadUpvalue(L, type, LuaClassNewIndexsFieldName, 1);
         int cls_setter = LuaAPI.lua_gettop(L);
            LuaCSFunction item_getter;
            LuaCSFunction item_setter;
            makeReflectionWrap(L, type, cls_field, cls_getter, cls_setter, obj_field, obj_getter, obj_setter, obj_meta,
                out item_getter, out item_setter, BindingFlags.NonPublic);
            LuaAPI.lua_settop(L, oldTop);
         LuaCSFunction item_getter;
         LuaCSFunction item_setter;
         makeReflectionWrap(L, type, cls_field, cls_getter, cls_setter, obj_field, obj_getter, obj_setter, obj_meta,
            out item_getter, out item_setter, BindingFlags.NonPublic);
         LuaAPI.lua_settop(L, oldTop);
            foreach (var nested_type in type.GetNestedTypes(BindingFlags.NonPublic))
            {
                if ((!nested_type.IsAbstract() && typeof(Delegate).IsAssignableFrom(nested_type))
                    || nested_type.IsGenericTypeDefinition())
                {
                    continue;
                }
                ObjectTranslatorPool.Instance.Find(L).TryDelayWrapLoader(L, nested_type);
                MakePrivateAccessible(L, nested_type);
            }
        }
         foreach (var nested_type in type.GetNestedTypes(BindingFlags.NonPublic))
         {
            if ((!nested_type.IsAbstract() && typeof(Delegate).IsAssignableFrom(nested_type))
               || nested_type.IsGenericTypeDefinition())
            {
               continue;
            }
            ObjectTranslatorPool.Instance.Find(L).TryDelayWrapLoader(L, nested_type);
            MakePrivateAccessible(L, nested_type);
         }
      }
        [MonoPInvokeCallback(typeof(LuaCSFunction))]
        internal static int LazyReflectionCall(RealStatePtr L)
        {
            try
            {
                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
                Type type;
                translator.Get(L, LuaAPI.xlua_upvalueindex(1), out type);
                LazyMemberTypes memberType = (LazyMemberTypes)LuaAPI.xlua_tointeger(L, LuaAPI.xlua_upvalueindex(2));
                string memberName = LuaAPI.lua_tostring(L, LuaAPI.xlua_upvalueindex(3));
                bool isStatic = LuaAPI.lua_toboolean(L, LuaAPI.xlua_upvalueindex(4));
                LuaCSFunction wrap = null;
                //UnityEngine.Debug.Log(">>>>> " + type + " " + memberName);
      [MonoPInvokeCallback(typeof(LuaCSFunction))]
      internal static int LazyReflectionCall(RealStatePtr L)
      {
         try
         {
            ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
            Type type;
            translator.Get(L, LuaAPI.xlua_upvalueindex(1), out type);
            LazyMemberTypes memberType = (LazyMemberTypes)LuaAPI.xlua_tointeger(L, LuaAPI.xlua_upvalueindex(2));
            string memberName = LuaAPI.lua_tostring(L, LuaAPI.xlua_upvalueindex(3));
            bool isStatic = LuaAPI.lua_toboolean(L, LuaAPI.xlua_upvalueindex(4));
            LuaCSFunction wrap = null;
            //UnityEngine.Debug.Log(">>>>> " + type + " " + memberName);
                switch (memberType)
                {
                    case LazyMemberTypes.Method:
                        var members = type.GetMember(memberName);
                        if (members == null || members.Length == 0)
                        {
                            return LuaAPI.luaL_error(L, "can not find " + memberName + " for " + type);
                        }
                        IEnumerable<MemberInfo> methods = members;
                        if (!isStatic)
                        {
                            var extensionMethods = GetExtensionMethodsOf(type);
                            if (extensionMethods != null)
                            {
                                methods = methods.Concat(extensionMethods.Where(m => m.Name == memberName).Cast<MemberInfo>());
                            }
                        }
                        wrap = new LuaCSFunction(translator.methodWrapsCache._GenMethodWrap(type, memberName, methods.ToArray()).Call);
                        if (isStatic)
                        {
                            LoadCSTable(L, type);
                        }
                        else
                        {
                            loadUpvalue(L, type, LuaIndexsFieldName, 1);
                        }
                        if (LuaAPI.lua_isnil(L, -1))
                        {
                            return LuaAPI.luaL_error(L, "can not find the meta info for " + type);
                        }
                        break;
                    case LazyMemberTypes.FieldGet:
                    case LazyMemberTypes.FieldSet:
                        var field = type.GetField(memberName);
                        if (field == null)
                        {
                            return LuaAPI.luaL_error(L, "can not find " + memberName + " for " + type);
                        }
                        if (isStatic)
                        {
                            if (memberType == LazyMemberTypes.FieldGet)
                            {
                                loadUpvalue(L, type, LuaClassIndexsFieldName, 1);
                            }
                            else
                            {
                                loadUpvalue(L, type, LuaClassNewIndexsFieldName, 1);
                            }
                        }
                        else
                        {
                            if (memberType == LazyMemberTypes.FieldGet)
                            {
                                loadUpvalue(L, type, LuaIndexsFieldName, 2);
                                LuaAPI.lua_remove(L, -2);
                            }
                            else
                            {
                                loadUpvalue(L, type, LuaNewIndexsFieldName, 1);
                            }
                        }
            switch (memberType)
            {
               case LazyMemberTypes.Method:
                  var members = type.GetMember(memberName);
                  if (members == null || members.Length == 0)
                  {
                     return LuaAPI.luaL_error(L, "can not find " + memberName + " for " + type);
                  }
                  IEnumerable<MemberInfo> methods = members;
                  if (!isStatic)
                  {
                     var extensionMethods = GetExtensionMethodsOf(type);
                     if (extensionMethods != null)
                     {
                        methods = methods.Concat(extensionMethods.Where(m => m.Name == memberName).Cast<MemberInfo>());
                     }
                  }
                  wrap = new LuaCSFunction(translator.methodWrapsCache._GenMethodWrap(type, memberName, methods.ToArray()).Call);
                  if (isStatic)
                  {
                     LoadCSTable(L, type);
                  }
                  else
                  {
                     loadUpvalue(L, type, LuaIndexsFieldName, 1);
                  }
                  if (LuaAPI.lua_isnil(L, -1))
                  {
                     return LuaAPI.luaL_error(L, "can not find the meta info for " + type);
                  }
                  break;
               case LazyMemberTypes.FieldGet:
               case LazyMemberTypes.FieldSet:
                  var field = type.GetField(memberName);
                  if (field == null)
                  {
                     return LuaAPI.luaL_error(L, "can not find " + memberName + " for " + type);
                  }
                  if (isStatic)
                  {
                     if (memberType == LazyMemberTypes.FieldGet)
                     {
                        loadUpvalue(L, type, LuaClassIndexsFieldName, 1);
                     }
                     else
                     {
                        loadUpvalue(L, type, LuaClassNewIndexsFieldName, 1);
                     }
                  }
                  else
                  {
                     if (memberType == LazyMemberTypes.FieldGet)
                     {
                        loadUpvalue(L, type, LuaIndexsFieldName, 2);
                        LuaAPI.lua_remove(L, -2);
                     }
                     else
                     {
                        loadUpvalue(L, type, LuaNewIndexsFieldName, 1);
                     }
                  }
                        wrap = (memberType == LazyMemberTypes.FieldGet) ? genFieldGetter(type, field) : genFieldSetter(type, field);
                  wrap = (memberType == LazyMemberTypes.FieldGet) ? genFieldGetter(type, field) : genFieldSetter(type, field);
                        break;
                    case LazyMemberTypes.PropertyGet:
                    case LazyMemberTypes.PropertySet:
                        var prop = type.GetProperty(memberName);
                        if (prop == null)
                        {
                            return LuaAPI.luaL_error(L, "can not find " + memberName + " for " + type);
                        }
                        if (isStatic)
                        {
                            if (memberType == LazyMemberTypes.PropertyGet)
                            {
                                loadUpvalue(L, type, LuaClassIndexsFieldName, 1);
                            }
                            else
                            {
                                loadUpvalue(L, type, LuaClassNewIndexsFieldName, 1);
                            }
                        }
                        else
                        {
                            if (memberType == LazyMemberTypes.PropertyGet)
                            {
                                loadUpvalue(L, type, LuaIndexsFieldName, 2);
                                LuaAPI.lua_remove(L, -2);
                            }
                            else
                            {
                                loadUpvalue(L, type, LuaNewIndexsFieldName, 1);
                            }
                        }
                  break;
               case LazyMemberTypes.PropertyGet:
               case LazyMemberTypes.PropertySet:
                  var prop = type.GetProperty(memberName);
                  if (prop == null)
                  {
                     return LuaAPI.luaL_error(L, "can not find " + memberName + " for " + type);
                  }
                  if (isStatic)
                  {
                     if (memberType == LazyMemberTypes.PropertyGet)
                     {
                        loadUpvalue(L, type, LuaClassIndexsFieldName, 1);
                     }
                     else
                     {
                        loadUpvalue(L, type, LuaClassNewIndexsFieldName, 1);
                     }
                  }
                  else
                  {
                     if (memberType == LazyMemberTypes.PropertyGet)
                     {
                        loadUpvalue(L, type, LuaIndexsFieldName, 2);
                        LuaAPI.lua_remove(L, -2);
                     }
                     else
                     {
                        loadUpvalue(L, type, LuaNewIndexsFieldName, 1);
                     }
                  }
                        if (LuaAPI.lua_isnil(L, -1))
                        {
                            return LuaAPI.luaL_error(L, "can not find the meta info for " + type);
                        }
                  if (LuaAPI.lua_isnil(L, -1))
                  {
                     return LuaAPI.luaL_error(L, "can not find the meta info for " + type);
                  }
                        wrap = translator.methodWrapsCache._GenMethodWrap(prop.DeclaringType, prop.Name, new MethodBase[] { (memberType == LazyMemberTypes.PropertyGet) ? prop.GetGetMethod() : prop.GetSetMethod() }).Call;
                        break;
                    case LazyMemberTypes.Event:
                        var eventInfo = type.GetEvent(memberName);
                        if (eventInfo == null)
                        {
                            return LuaAPI.luaL_error(L, "can not find " + memberName + " for " + type);
                        }
                        if (isStatic)
                        {
                            LoadCSTable(L, type);
                        }
                        else
                        {
                            loadUpvalue(L, type, LuaIndexsFieldName, 1);
                        }
                        if (LuaAPI.lua_isnil(L, -1))
                        {
                            return LuaAPI.luaL_error(L, "can not find the meta info for " + type);
                        }
                        wrap = translator.methodWrapsCache.GetEventWrap(type, eventInfo.Name);
                        break;
                    default:
                        return LuaAPI.luaL_error(L, "unsupport member type" + memberType);
                }
                  wrap = translator.methodWrapsCache._GenMethodWrap(prop.DeclaringType, prop.Name, new MethodBase[] { (memberType == LazyMemberTypes.PropertyGet) ? prop.GetGetMethod() : prop.GetSetMethod() }).Call;
                  break;
               case LazyMemberTypes.Event:
                  var eventInfo = type.GetEvent(memberName);
                  if (eventInfo == null)
                  {
                     return LuaAPI.luaL_error(L, "can not find " + memberName + " for " + type);
                  }
                  if (isStatic)
                  {
                     LoadCSTable(L, type);
                  }
                  else
                  {
                     loadUpvalue(L, type, LuaIndexsFieldName, 1);
                  }
                  if (LuaAPI.lua_isnil(L, -1))
                  {
                     return LuaAPI.luaL_error(L, "can not find the meta info for " + type);
                  }
                  wrap = translator.methodWrapsCache.GetEventWrap(type, eventInfo.Name);
                  break;
               default:
                  return LuaAPI.luaL_error(L, "unsupport member type" + memberType);
            }
                LuaAPI.xlua_pushasciistring(L, memberName);
                translator.PushFixCSFunction(L, wrap);
                LuaAPI.lua_rawset(L, -3);
                LuaAPI.lua_pop(L, 1);
                return wrap(L);
            }
            catch (Exception e)
            {
                return LuaAPI.luaL_error(L, "c# exception in LazyReflectionCall:" + e);
            }
        }
            LuaAPI.xlua_pushasciistring(L, memberName);
            translator.PushFixCSFunction(L, wrap);
            LuaAPI.lua_rawset(L, -3);
            LuaAPI.lua_pop(L, 1);
            return wrap(L);
         }
         catch (Exception e)
         {
            return LuaAPI.luaL_error(L, "c# exception in LazyReflectionCall:" + e);
         }
      }
        public static void ReflectionWrap(RealStatePtr L, Type type, bool privateAccessible)
        {
            int top_enter = LuaAPI.lua_gettop(L);
            ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
            //create obj meta table
            LuaAPI.luaL_getmetatable(L, type.FullName);
            if (LuaAPI.lua_isnil(L, -1))
            {
                LuaAPI.lua_pop(L, 1);
                LuaAPI.luaL_newmetatable(L, type.FullName);
            }
            LuaAPI.lua_pushlightuserdata(L, LuaAPI.xlua_tag());
            LuaAPI.lua_pushnumber(L, 1);
            LuaAPI.lua_rawset(L, -3);
            int obj_meta = LuaAPI.lua_gettop(L);
      public static void ReflectionWrap(RealStatePtr L, Type type, bool privateAccessible)
      {
         int top_enter = LuaAPI.lua_gettop(L);
         ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
         //create obj meta table
         LuaAPI.luaL_getmetatable(L, type.FullName);
         if (LuaAPI.lua_isnil(L, -1))
         {
            LuaAPI.lua_pop(L, 1);
            LuaAPI.luaL_newmetatable(L, type.FullName);
         }
         LuaAPI.lua_pushlightuserdata(L, LuaAPI.xlua_tag());
         LuaAPI.lua_pushnumber(L, 1);
         LuaAPI.lua_rawset(L, -3);
         int obj_meta = LuaAPI.lua_gettop(L);
            LuaAPI.lua_newtable(L);
            int cls_meta = LuaAPI.lua_gettop(L);
         LuaAPI.lua_newtable(L);
         int cls_meta = LuaAPI.lua_gettop(L);
            LuaAPI.lua_newtable(L);
            int obj_field = LuaAPI.lua_gettop(L);
            LuaAPI.lua_newtable(L);
            int obj_getter = LuaAPI.lua_gettop(L);
            LuaAPI.lua_newtable(L);
            int obj_setter = LuaAPI.lua_gettop(L);
            LuaAPI.lua_newtable(L);
            int cls_field = LuaAPI.lua_gettop(L);
            LuaAPI.lua_newtable(L);
            int cls_getter = LuaAPI.lua_gettop(L);
            LuaAPI.lua_newtable(L);
            int cls_setter = LuaAPI.lua_gettop(L);
         LuaAPI.lua_newtable(L);
         int obj_field = LuaAPI.lua_gettop(L);
         LuaAPI.lua_newtable(L);
         int obj_getter = LuaAPI.lua_gettop(L);
         LuaAPI.lua_newtable(L);
         int obj_setter = LuaAPI.lua_gettop(L);
         LuaAPI.lua_newtable(L);
         int cls_field = LuaAPI.lua_gettop(L);
         LuaAPI.lua_newtable(L);
         int cls_getter = LuaAPI.lua_gettop(L);
         LuaAPI.lua_newtable(L);
         int cls_setter = LuaAPI.lua_gettop(L);
            LuaCSFunction item_getter;
            LuaCSFunction item_setter;
            makeReflectionWrap(L, type, cls_field, cls_getter, cls_setter, obj_field, obj_getter, obj_setter, obj_meta,
                out item_getter, out item_setter, privateAccessible ? (BindingFlags.Public | BindingFlags.NonPublic) : BindingFlags.Public);
         LuaCSFunction item_getter;
         LuaCSFunction item_setter;
         makeReflectionWrap(L, type, cls_field, cls_getter, cls_setter, obj_field, obj_getter, obj_setter, obj_meta,
            out item_getter, out item_setter, privateAccessible ? (BindingFlags.Public | BindingFlags.NonPublic) : BindingFlags.Public);
            // init obj metatable
            LuaAPI.xlua_pushasciistring(L, "__gc");
            LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.GcMeta);
            LuaAPI.lua_rawset(L, obj_meta);
         // init obj metatable
         LuaAPI.xlua_pushasciistring(L, "__gc");
         LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.GcMeta);
         LuaAPI.lua_rawset(L, obj_meta);
            LuaAPI.xlua_pushasciistring(L, "__tostring");
            LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.ToStringMeta);
            LuaAPI.lua_rawset(L, obj_meta);
         LuaAPI.xlua_pushasciistring(L, "__tostring");
         LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.ToStringMeta);
         LuaAPI.lua_rawset(L, obj_meta);
            LuaAPI.xlua_pushasciistring(L, "__index");
            LuaAPI.lua_pushvalue(L, obj_field);
            LuaAPI.lua_pushvalue(L, obj_getter);
            translator.PushFixCSFunction(L, item_getter);
            translator.PushAny(L, type.BaseType());
            LuaAPI.xlua_pushasciistring(L, LuaIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            LuaAPI.lua_pushnil(L);
            LuaAPI.gen_obj_indexer(L);
            //store in lua indexs function tables
            LuaAPI.xlua_pushasciistring(L, LuaIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            translator.Push(L, type);
            LuaAPI.lua_pushvalue(L, -3);
            LuaAPI.lua_rawset(L, -3);
            LuaAPI.lua_pop(L, 1);
            LuaAPI.lua_rawset(L, obj_meta); // set __index
         LuaAPI.xlua_pushasciistring(L, "__index");
         LuaAPI.lua_pushvalue(L, obj_field);
         LuaAPI.lua_pushvalue(L, obj_getter);
         translator.PushFixCSFunction(L, item_getter);
         translator.PushAny(L, type.BaseType());
         LuaAPI.xlua_pushasciistring(L, LuaIndexsFieldName);
         LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
         LuaAPI.lua_pushnil(L);
         LuaAPI.gen_obj_indexer(L);
         //store in lua indexs function tables
         LuaAPI.xlua_pushasciistring(L, LuaIndexsFieldName);
         LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
         translator.Push(L, type);
         LuaAPI.lua_pushvalue(L, -3);
         LuaAPI.lua_rawset(L, -3);
         LuaAPI.lua_pop(L, 1);
         LuaAPI.lua_rawset(L, obj_meta); // set __index
            LuaAPI.xlua_pushasciistring(L, "__newindex");
            LuaAPI.lua_pushvalue(L, obj_setter);
            translator.PushFixCSFunction(L, item_setter);
            translator.Push(L, type.BaseType());
            LuaAPI.xlua_pushasciistring(L, LuaNewIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            LuaAPI.lua_pushnil(L);
            LuaAPI.gen_obj_newindexer(L);
            //store in lua newindexs function tables
            LuaAPI.xlua_pushasciistring(L, LuaNewIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            translator.Push(L, type);
            LuaAPI.lua_pushvalue(L, -3);
            LuaAPI.lua_rawset(L, -3);
            LuaAPI.lua_pop(L, 1);
            LuaAPI.lua_rawset(L, obj_meta); // set __newindex
            //finish init obj metatable
         LuaAPI.xlua_pushasciistring(L, "__newindex");
         LuaAPI.lua_pushvalue(L, obj_setter);
         translator.PushFixCSFunction(L, item_setter);
         translator.Push(L, type.BaseType());
         LuaAPI.xlua_pushasciistring(L, LuaNewIndexsFieldName);
         LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
         LuaAPI.lua_pushnil(L);
         LuaAPI.gen_obj_newindexer(L);
         //store in lua newindexs function tables
         LuaAPI.xlua_pushasciistring(L, LuaNewIndexsFieldName);
         LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
         translator.Push(L, type);
         LuaAPI.lua_pushvalue(L, -3);
         LuaAPI.lua_rawset(L, -3);
         LuaAPI.lua_pop(L, 1);
         LuaAPI.lua_rawset(L, obj_meta); // set __newindex
                                 //finish init obj metatable
            LuaAPI.xlua_pushasciistring(L, "UnderlyingSystemType");
            translator.PushAny(L, type);
            LuaAPI.lua_rawset(L, cls_field);
         LuaAPI.xlua_pushasciistring(L, "UnderlyingSystemType");
         translator.PushAny(L, type);
         LuaAPI.lua_rawset(L, cls_field);
            if (type != null && type.IsEnum())
            {
                LuaAPI.xlua_pushasciistring(L, "__CastFrom");
                translator.PushFixCSFunction(L, genEnumCastFrom(type));
                LuaAPI.lua_rawset(L, cls_field);
            }
         if (type != null && type.IsEnum())
         {
            LuaAPI.xlua_pushasciistring(L, "__CastFrom");
            translator.PushFixCSFunction(L, genEnumCastFrom(type));
            LuaAPI.lua_rawset(L, cls_field);
         }
            //set cls_field to namespace
            SetCSTable(L, type, cls_field);
            //finish set cls_field to namespace
         //set cls_field to namespace
         SetCSTable(L, type, cls_field);
         //finish set cls_field to namespace
            //init class meta
            LuaAPI.xlua_pushasciistring(L, "__index");
            LuaAPI.lua_pushvalue(L, cls_getter);
            LuaAPI.lua_pushvalue(L, cls_field);
            translator.Push(L, type.BaseType());
            LuaAPI.xlua_pushasciistring(L, LuaClassIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            LuaAPI.gen_cls_indexer(L);
            //store in lua indexs function tables
            LuaAPI.xlua_pushasciistring(L, LuaClassIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            translator.Push(L, type);
            LuaAPI.lua_pushvalue(L, -3);
            LuaAPI.lua_rawset(L, -3);
            LuaAPI.lua_pop(L, 1);
            LuaAPI.lua_rawset(L, cls_meta); // set __index
         //init class meta
         LuaAPI.xlua_pushasciistring(L, "__index");
         LuaAPI.lua_pushvalue(L, cls_getter);
         LuaAPI.lua_pushvalue(L, cls_field);
         translator.Push(L, type.BaseType());
         LuaAPI.xlua_pushasciistring(L, LuaClassIndexsFieldName);
         LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
         LuaAPI.gen_cls_indexer(L);
         //store in lua indexs function tables
         LuaAPI.xlua_pushasciistring(L, LuaClassIndexsFieldName);
         LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
         translator.Push(L, type);
         LuaAPI.lua_pushvalue(L, -3);
         LuaAPI.lua_rawset(L, -3);
         LuaAPI.lua_pop(L, 1);
         LuaAPI.lua_rawset(L, cls_meta); // set __index
            LuaAPI.xlua_pushasciistring(L, "__newindex");
            LuaAPI.lua_pushvalue(L, cls_setter);
            translator.Push(L, type.BaseType());
            LuaAPI.xlua_pushasciistring(L, LuaClassNewIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            LuaAPI.gen_cls_newindexer(L);
            //store in lua newindexs function tables
            LuaAPI.xlua_pushasciistring(L, LuaClassNewIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            translator.Push(L, type);
            LuaAPI.lua_pushvalue(L, -3);
            LuaAPI.lua_rawset(L, -3);
            LuaAPI.lua_pop(L, 1);
            LuaAPI.lua_rawset(L, cls_meta); // set __newindex
         LuaAPI.xlua_pushasciistring(L, "__newindex");
         LuaAPI.lua_pushvalue(L, cls_setter);
         translator.Push(L, type.BaseType());
         LuaAPI.xlua_pushasciistring(L, LuaClassNewIndexsFieldName);
         LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
         LuaAPI.gen_cls_newindexer(L);
         //store in lua newindexs function tables
         LuaAPI.xlua_pushasciistring(L, LuaClassNewIndexsFieldName);
         LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
         translator.Push(L, type);
         LuaAPI.lua_pushvalue(L, -3);
         LuaAPI.lua_rawset(L, -3);
         LuaAPI.lua_pop(L, 1);
         LuaAPI.lua_rawset(L, cls_meta); // set __newindex
            LuaCSFunction constructor = typeof(Delegate).IsAssignableFrom(type)? translator.metaFunctions.DelegateCtor : translator.methodWrapsCache.GetConstructorWrap(type);
            if (constructor == null)
            {
                constructor = (RealStatePtr LL) =>
                {
                    return LuaAPI.luaL_error(LL, "No constructor for " + type);
                };
            }
         LuaCSFunction constructor = typeof(Delegate).IsAssignableFrom(type) ? translator.metaFunctions.DelegateCtor : translator.methodWrapsCache.GetConstructorWrap(type);
         if (constructor == null)
         {
            constructor = (RealStatePtr LL) =>
            {
               return LuaAPI.luaL_error(LL, "No constructor for " + type);
            };
         }
            LuaAPI.xlua_pushasciistring(L, "__call");
            translator.PushFixCSFunction(L, constructor);
            LuaAPI.lua_rawset(L, cls_meta);
         LuaAPI.xlua_pushasciistring(L, "__call");
         translator.PushFixCSFunction(L, constructor);
         LuaAPI.lua_rawset(L, cls_meta);
            LuaAPI.lua_pushvalue(L, cls_meta);
            LuaAPI.lua_setmetatable(L, cls_field);
         LuaAPI.lua_pushvalue(L, cls_meta);
         LuaAPI.lua_setmetatable(L, cls_field);
            LuaAPI.lua_pop(L, 8);
         LuaAPI.lua_pop(L, 8);
            System.Diagnostics.Debug.Assert(top_enter == LuaAPI.lua_gettop(L));
        }
         System.Diagnostics.Debug.Assert(top_enter == LuaAPI.lua_gettop(L));
      }
        //meta: -4, method:-3, getter: -2, setter: -1
        public static void BeginObjectRegister(Type type, RealStatePtr L, ObjectTranslator translator, int meta_count, int method_count, int getter_count,
            int setter_count, int type_id = -1)
        {
            if (type == null)
            {
                if (type_id == -1) throw new Exception("Fatal: must provide a type of type_id");
                LuaAPI.xlua_rawgeti(L, LuaIndexes.LUA_REGISTRYINDEX, type_id);
            }
            else
            {
                LuaAPI.luaL_getmetatable(L, type.FullName);
                if (LuaAPI.lua_isnil(L, -1))
                {
                    LuaAPI.lua_pop(L, 1);
                    LuaAPI.luaL_newmetatable(L, type.FullName);
                }
            }
            LuaAPI.lua_pushlightuserdata(L, LuaAPI.xlua_tag());
            LuaAPI.lua_pushnumber(L, 1);
            LuaAPI.lua_rawset(L, -3);
      //meta: -4, method:-3, getter: -2, setter: -1
      public static void BeginObjectRegister(Type type, RealStatePtr L, ObjectTranslator translator, int meta_count, int method_count, int getter_count,
         int setter_count, int type_id = -1)
      {
         if (type == null)
         {
            if (type_id == -1) throw new Exception("Fatal: must provide a type of type_id");
            LuaAPI.xlua_rawgeti(L, LuaIndexes.LUA_REGISTRYINDEX, type_id);
         }
         else
         {
            LuaAPI.luaL_getmetatable(L, type.FullName);
            if (LuaAPI.lua_isnil(L, -1))
            {
               LuaAPI.lua_pop(L, 1);
               LuaAPI.luaL_newmetatable(L, type.FullName);
            }
         }
         LuaAPI.lua_pushlightuserdata(L, LuaAPI.xlua_tag());
         LuaAPI.lua_pushnumber(L, 1);
         LuaAPI.lua_rawset(L, -3);
            if ((type == null || !translator.HasCustomOp(type)) && type != typeof(decimal))
            {
                LuaAPI.xlua_pushasciistring(L, "__gc");
                LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.GcMeta);
                LuaAPI.lua_rawset(L, -3);
            }
         if ((type == null || !translator.HasCustomOp(type)) && type != typeof(decimal))
         {
            LuaAPI.xlua_pushasciistring(L, "__gc");
            LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.GcMeta);
            LuaAPI.lua_rawset(L, -3);
         }
            LuaAPI.xlua_pushasciistring(L, "__tostring");
            LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.ToStringMeta);
            LuaAPI.lua_rawset(L, -3);
         LuaAPI.xlua_pushasciistring(L, "__tostring");
         LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.ToStringMeta);
         LuaAPI.lua_rawset(L, -3);
            if (method_count == 0)
            {
                LuaAPI.lua_pushnil(L);
            }
            else
            {
                LuaAPI.lua_createtable(L, 0, method_count);
            }
         if (method_count == 0)
         {
            LuaAPI.lua_pushnil(L);
         }
         else
         {
            LuaAPI.lua_createtable(L, 0, method_count);
         }
            if (getter_count == 0)
            {
                LuaAPI.lua_pushnil(L);
            }
            else
            {
                LuaAPI.lua_createtable(L, 0, getter_count);
            }
         if (getter_count == 0)
         {
            LuaAPI.lua_pushnil(L);
         }
         else
         {
            LuaAPI.lua_createtable(L, 0, getter_count);
         }
            if (setter_count == 0)
            {
                LuaAPI.lua_pushnil(L);
            }
            else
            {
                LuaAPI.lua_createtable(L, 0, setter_count);
            }
        }
         if (setter_count == 0)
         {
            LuaAPI.lua_pushnil(L);
         }
         else
         {
            LuaAPI.lua_createtable(L, 0, setter_count);
         }
      }
        static int abs_idx(int top, int idx)
        {
            return idx > 0 ? idx : top + idx + 1;
        }
      static int abs_idx(int top, int idx)
      {
         return idx > 0 ? idx : top + idx + 1;
      }
        public const int OBJ_META_IDX = -4;
        public const int METHOD_IDX = -3;
        public const int GETTER_IDX = -2;
        public const int SETTER_IDX = -1;
      public const int OBJ_META_IDX = -4;
      public const int METHOD_IDX = -3;
      public const int GETTER_IDX = -2;
      public const int SETTER_IDX = -1;
#if GEN_CODE_MINIMIZE
        public static void EndObjectRegister(Type type, RealStatePtr L, ObjectTranslator translator, CSharpWrapper csIndexer,
            CSharpWrapper csNewIndexer, Type base_type, CSharpWrapper arrayIndexer, CSharpWrapper arrayNewIndexer)
#else
        public static void EndObjectRegister(Type type, RealStatePtr L, ObjectTranslator translator, LuaCSFunction csIndexer,
            LuaCSFunction csNewIndexer, Type base_type, LuaCSFunction arrayIndexer, LuaCSFunction arrayNewIndexer)
      public static void EndObjectRegister(Type type, RealStatePtr L, ObjectTranslator translator, LuaCSFunction csIndexer,
         LuaCSFunction csNewIndexer, Type base_type, LuaCSFunction arrayIndexer, LuaCSFunction arrayNewIndexer)
#endif
        {
            int top = LuaAPI.lua_gettop(L);
            int meta_idx = abs_idx(top, OBJ_META_IDX);
            int method_idx = abs_idx(top, METHOD_IDX);
            int getter_idx = abs_idx(top, GETTER_IDX);
            int setter_idx = abs_idx(top, SETTER_IDX);
      {
         int top = LuaAPI.lua_gettop(L);
         int meta_idx = abs_idx(top, OBJ_META_IDX);
         int method_idx = abs_idx(top, METHOD_IDX);
         int getter_idx = abs_idx(top, GETTER_IDX);
         int setter_idx = abs_idx(top, SETTER_IDX);
            //begin index gen
            LuaAPI.xlua_pushasciistring(L, "__index");
            LuaAPI.lua_pushvalue(L, method_idx);
            LuaAPI.lua_pushvalue(L, getter_idx);
         //begin index gen
         LuaAPI.xlua_pushasciistring(L, "__index");
         LuaAPI.lua_pushvalue(L, method_idx);
         LuaAPI.lua_pushvalue(L, getter_idx);
            if (csIndexer == null)
            {
                LuaAPI.lua_pushnil(L);
            }
            else
            {
         if (csIndexer == null)
         {
            LuaAPI.lua_pushnil(L);
         }
         else
         {
#if GEN_CODE_MINIMIZE
                translator.PushCSharpWrapper(L, csIndexer);
#else
                LuaAPI.lua_pushstdcallcfunction(L, csIndexer);
            LuaAPI.lua_pushstdcallcfunction(L, csIndexer);
#endif
            }
         }
            translator.Push(L, type == null ? base_type : type.BaseType());
         translator.Push(L, type == null ? base_type : type.BaseType());
            LuaAPI.xlua_pushasciistring(L, LuaIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            if (arrayIndexer == null)
            {
                LuaAPI.lua_pushnil(L);
            }
            else
            {
         LuaAPI.xlua_pushasciistring(L, LuaIndexsFieldName);
         LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
         if (arrayIndexer == null)
         {
            LuaAPI.lua_pushnil(L);
         }
         else
         {
#if GEN_CODE_MINIMIZE
                translator.PushCSharpWrapper(L, arrayIndexer);
#else
                LuaAPI.lua_pushstdcallcfunction(L, arrayIndexer);
            LuaAPI.lua_pushstdcallcfunction(L, arrayIndexer);
#endif
            }
         }
            LuaAPI.gen_obj_indexer(L);
         LuaAPI.gen_obj_indexer(L);
            if (type != null)
            {
                LuaAPI.xlua_pushasciistring(L, LuaIndexsFieldName);
                LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);//store in lua indexs function tables
                translator.Push(L, type);
                LuaAPI.lua_pushvalue(L, -3);
                LuaAPI.lua_rawset(L, -3);
                LuaAPI.lua_pop(L, 1);
            }
         if (type != null)
         {
            LuaAPI.xlua_pushasciistring(L, LuaIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);//store in lua indexs function tables
            translator.Push(L, type);
            LuaAPI.lua_pushvalue(L, -3);
            LuaAPI.lua_rawset(L, -3);
            LuaAPI.lua_pop(L, 1);
         }
            LuaAPI.lua_rawset(L, meta_idx);
            //end index gen
         LuaAPI.lua_rawset(L, meta_idx);
         //end index gen
            //begin newindex gen
            LuaAPI.xlua_pushasciistring(L, "__newindex");
            LuaAPI.lua_pushvalue(L, setter_idx);
         //begin newindex gen
         LuaAPI.xlua_pushasciistring(L, "__newindex");
         LuaAPI.lua_pushvalue(L, setter_idx);
            if (csNewIndexer == null)
            {
                LuaAPI.lua_pushnil(L);
            }
            else
            {
         if (csNewIndexer == null)
         {
            LuaAPI.lua_pushnil(L);
         }
         else
         {
#if GEN_CODE_MINIMIZE
                translator.PushCSharpWrapper(L, csNewIndexer);
#else
                LuaAPI.lua_pushstdcallcfunction(L, csNewIndexer);
            LuaAPI.lua_pushstdcallcfunction(L, csNewIndexer);
#endif
            }
         }
            translator.Push(L, type == null ? base_type : type.BaseType());
         translator.Push(L, type == null ? base_type : type.BaseType());
            LuaAPI.xlua_pushasciistring(L, LuaNewIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
         LuaAPI.xlua_pushasciistring(L, LuaNewIndexsFieldName);
         LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            if (arrayNewIndexer == null)
            {
                LuaAPI.lua_pushnil(L);
            }
            else
            {
         if (arrayNewIndexer == null)
         {
            LuaAPI.lua_pushnil(L);
         }
         else
         {
#if GEN_CODE_MINIMIZE
                translator.PushCSharpWrapper(L, arrayNewIndexer);
#else
                LuaAPI.lua_pushstdcallcfunction(L, arrayNewIndexer);
            LuaAPI.lua_pushstdcallcfunction(L, arrayNewIndexer);
#endif
            }
         }
            LuaAPI.gen_obj_newindexer(L);
         LuaAPI.gen_obj_newindexer(L);
            if (type != null)
            {
                LuaAPI.xlua_pushasciistring(L, LuaNewIndexsFieldName);
                LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);//store in lua newindexs function tables
                translator.Push(L, type);
                LuaAPI.lua_pushvalue(L, -3);
                LuaAPI.lua_rawset(L, -3);
                LuaAPI.lua_pop(L, 1);
            }
         if (type != null)
         {
            LuaAPI.xlua_pushasciistring(L, LuaNewIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);//store in lua newindexs function tables
            translator.Push(L, type);
            LuaAPI.lua_pushvalue(L, -3);
            LuaAPI.lua_rawset(L, -3);
            LuaAPI.lua_pop(L, 1);
         }
            LuaAPI.lua_rawset(L, meta_idx);
            //end new index gen
            LuaAPI.lua_pop(L, 4);
        }
         LuaAPI.lua_rawset(L, meta_idx);
         //end new index gen
         LuaAPI.lua_pop(L, 4);
      }
#if GEN_CODE_MINIMIZE
        public static void RegisterFunc(RealStatePtr L, int idx, string name, CSharpWrapper func)
@@ -1149,367 +1153,373 @@
            LuaAPI.lua_rawset(L, idx);
        }
#else
        public static void RegisterFunc(RealStatePtr L, int idx, string name, LuaCSFunction func)
        {
            idx = abs_idx(LuaAPI.lua_gettop(L), idx);
            LuaAPI.xlua_pushasciistring(L, name);
            LuaAPI.lua_pushstdcallcfunction(L, func);
            LuaAPI.lua_rawset(L, idx);
        }
      public static void RegisterFunc(RealStatePtr L, int idx, string name, LuaCSFunction func)
      {
         idx = abs_idx(LuaAPI.lua_gettop(L), idx);
         LuaAPI.xlua_pushasciistring(L, name);
         LuaAPI.lua_pushstdcallcfunction(L, func);
         LuaAPI.lua_rawset(L, idx);
      }
#endif
        public static void RegisterLazyFunc(RealStatePtr L, int idx, string name, Type type, LazyMemberTypes memberType, bool isStatic)
        {
            idx = abs_idx(LuaAPI.lua_gettop(L), idx);
            LuaAPI.xlua_pushasciistring(L, name);
      public static void RegisterLazyFunc(RealStatePtr L, int idx, string name, Type type, LazyMemberTypes memberType, bool isStatic)
      {
         idx = abs_idx(LuaAPI.lua_gettop(L), idx);
         LuaAPI.xlua_pushasciistring(L, name);
            ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
            translator.PushAny(L, type);
            LuaAPI.xlua_pushinteger(L, (int)memberType);
            LuaAPI.lua_pushstring(L, name);
            LuaAPI.lua_pushboolean(L, isStatic);
            LuaAPI.lua_pushstdcallcfunction(L, InternalGlobals.LazyReflectionWrap, 4);
            LuaAPI.lua_rawset(L, idx);
        }
         ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
         translator.PushAny(L, type);
         LuaAPI.xlua_pushinteger(L, (int)memberType);
         LuaAPI.lua_pushstring(L, name);
         LuaAPI.lua_pushboolean(L, isStatic);
         LuaAPI.lua_pushstdcallcfunction(L, InternalGlobals.LazyReflectionWrap, 4);
         LuaAPI.lua_rawset(L, idx);
      }
        public static void RegisterObject(RealStatePtr L, ObjectTranslator translator, int idx, string name, object obj)
        {
            idx = abs_idx(LuaAPI.lua_gettop(L), idx);
            LuaAPI.xlua_pushasciistring(L, name);
            translator.PushAny(L, obj);
            LuaAPI.lua_rawset(L, idx);
        }
      public static void RegisterObject(RealStatePtr L, ObjectTranslator translator, int idx, string name, object obj)
      {
         idx = abs_idx(LuaAPI.lua_gettop(L), idx);
         LuaAPI.xlua_pushasciistring(L, name);
         translator.PushAny(L, obj);
         LuaAPI.lua_rawset(L, idx);
      }
#if GEN_CODE_MINIMIZE
        public static void BeginClassRegister(Type type, RealStatePtr L, CSharpWrapper creator, int class_field_count,
            int static_getter_count, int static_setter_count)
#else
        public static void BeginClassRegister(Type type, RealStatePtr L, LuaCSFunction creator, int class_field_count,
            int static_getter_count, int static_setter_count)
      public static void BeginClassRegister(Type type, RealStatePtr L, LuaCSFunction creator, int class_field_count,
         int static_getter_count, int static_setter_count)
#endif
        {
            ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
            LuaAPI.lua_createtable(L, 0, class_field_count);
      {
         ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
         LuaAPI.lua_createtable(L, 0, class_field_count);
            LuaAPI.xlua_pushasciistring(L, "UnderlyingSystemType");
            translator.PushAny(L, type);
            LuaAPI.lua_rawset(L, -3);
         LuaAPI.xlua_pushasciistring(L, "UnderlyingSystemType");
         translator.PushAny(L, type);
         LuaAPI.lua_rawset(L, -3);
            int cls_table = LuaAPI.lua_gettop(L);
         int cls_table = LuaAPI.lua_gettop(L);
            SetCSTable(L, type, cls_table);
         SetCSTable(L, type, cls_table);
            LuaAPI.lua_createtable(L, 0, 3);
            int meta_table = LuaAPI.lua_gettop(L);
            if (creator != null)
            {
                LuaAPI.xlua_pushasciistring(L, "__call");
         LuaAPI.lua_createtable(L, 0, 3);
         int meta_table = LuaAPI.lua_gettop(L);
         if (creator != null)
         {
            LuaAPI.xlua_pushasciistring(L, "__call");
#if GEN_CODE_MINIMIZE
                translator.PushCSharpWrapper(L, creator);
#else
                LuaAPI.lua_pushstdcallcfunction(L, creator);
            LuaAPI.lua_pushstdcallcfunction(L, creator);
#endif
                LuaAPI.lua_rawset(L, -3);
            }
            LuaAPI.lua_rawset(L, -3);
         }
            if (static_getter_count == 0)
            {
                LuaAPI.lua_pushnil(L);
            }
            else
            {
                LuaAPI.lua_createtable(L, 0, static_getter_count);
            }
            if (static_setter_count == 0)
            {
                LuaAPI.lua_pushnil(L);
            }
            else
            {
                LuaAPI.lua_createtable(L, 0, static_setter_count);
            }
            LuaAPI.lua_pushvalue(L, meta_table);
            LuaAPI.lua_setmetatable(L, cls_table);
        }
         if (static_getter_count == 0)
         {
            LuaAPI.lua_pushnil(L);
         }
         else
         {
            LuaAPI.lua_createtable(L, 0, static_getter_count);
         }
        public const int CLS_IDX = -4;
        public const int CLS_META_IDX = -3;
        public const int CLS_GETTER_IDX = -2;
        public const int CLS_SETTER_IDX = -1;
         if (static_setter_count == 0)
         {
            LuaAPI.lua_pushnil(L);
         }
         else
         {
            LuaAPI.lua_createtable(L, 0, static_setter_count);
         }
         LuaAPI.lua_pushvalue(L, meta_table);
         LuaAPI.lua_setmetatable(L, cls_table);
      }
        public static void EndClassRegister(Type type, RealStatePtr L, ObjectTranslator translator)
        {
            int top = LuaAPI.lua_gettop(L);
            int cls_idx = abs_idx(top, CLS_IDX);
            int cls_getter_idx = abs_idx(top, CLS_GETTER_IDX);
            int cls_setter_idx = abs_idx(top, CLS_SETTER_IDX);
            int cls_meta_idx = abs_idx(top, CLS_META_IDX);
            //begin cls index
            LuaAPI.xlua_pushasciistring(L, "__index");
            LuaAPI.lua_pushvalue(L, cls_getter_idx);
            LuaAPI.lua_pushvalue(L, cls_idx);
            translator.Push(L, type.BaseType());
            LuaAPI.xlua_pushasciistring(L, LuaClassIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            LuaAPI.gen_cls_indexer(L);
      public const int CLS_IDX = -4;
      public const int CLS_META_IDX = -3;
      public const int CLS_GETTER_IDX = -2;
      public const int CLS_SETTER_IDX = -1;
            LuaAPI.xlua_pushasciistring(L, LuaClassIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);//store in lua indexs function tables
            translator.Push(L, type);
            LuaAPI.lua_pushvalue(L, -3);
            LuaAPI.lua_rawset(L, -3);
            LuaAPI.lua_pop(L, 1);
      public static void EndClassRegister(Type type, RealStatePtr L, ObjectTranslator translator)
      {
         int top = LuaAPI.lua_gettop(L);
         int cls_idx = abs_idx(top, CLS_IDX);
         int cls_getter_idx = abs_idx(top, CLS_GETTER_IDX);
         int cls_setter_idx = abs_idx(top, CLS_SETTER_IDX);
         int cls_meta_idx = abs_idx(top, CLS_META_IDX);
            LuaAPI.lua_rawset(L, cls_meta_idx);
            //end cls index
         //begin cls index
         LuaAPI.xlua_pushasciistring(L, "__index");
         LuaAPI.lua_pushvalue(L, cls_getter_idx);
         LuaAPI.lua_pushvalue(L, cls_idx);
         translator.Push(L, type.BaseType());
         LuaAPI.xlua_pushasciistring(L, LuaClassIndexsFieldName);
         LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
         LuaAPI.gen_cls_indexer(L);
            //begin cls newindex
            LuaAPI.xlua_pushasciistring(L, "__newindex");
            LuaAPI.lua_pushvalue(L, cls_setter_idx);
            translator.Push(L, type.BaseType());
            LuaAPI.xlua_pushasciistring(L, LuaClassNewIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            LuaAPI.gen_cls_newindexer(L);
         LuaAPI.xlua_pushasciistring(L, LuaClassIndexsFieldName);
         LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);//store in lua indexs function tables
         translator.Push(L, type);
         LuaAPI.lua_pushvalue(L, -3);
         LuaAPI.lua_rawset(L, -3);
         LuaAPI.lua_pop(L, 1);
            LuaAPI.xlua_pushasciistring(L, LuaClassNewIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);//store in lua newindexs function tables
            translator.Push(L, type);
            LuaAPI.lua_pushvalue(L, -3);
            LuaAPI.lua_rawset(L, -3);
            LuaAPI.lua_pop(L, 1);
         LuaAPI.lua_rawset(L, cls_meta_idx);
         //end cls index
            LuaAPI.lua_rawset(L, cls_meta_idx);
            //end cls newindex
         //begin cls newindex
         LuaAPI.xlua_pushasciistring(L, "__newindex");
         LuaAPI.lua_pushvalue(L, cls_setter_idx);
         translator.Push(L, type.BaseType());
         LuaAPI.xlua_pushasciistring(L, LuaClassNewIndexsFieldName);
         LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
         LuaAPI.gen_cls_newindexer(L);
            LuaAPI.lua_pop(L, 4);
        }
         LuaAPI.xlua_pushasciistring(L, LuaClassNewIndexsFieldName);
         LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);//store in lua newindexs function tables
         translator.Push(L, type);
         LuaAPI.lua_pushvalue(L, -3);
         LuaAPI.lua_rawset(L, -3);
         LuaAPI.lua_pop(L, 1);
        static List<string> getPathOfType(Type type)
        {
            List<string> path = new List<string>();
         LuaAPI.lua_rawset(L, cls_meta_idx);
         //end cls newindex
            if (type.Namespace != null)
            {
                path.AddRange(type.Namespace.Split(new char[] { '.' }));
            }
         LuaAPI.lua_pop(L, 4);
      }
            string class_name = type.ToString().Substring(type.Namespace == null ? 0 : type.Namespace.Length + 1);
      static List<string> getPathOfType(Type type)
      {
         List<string> path = new List<string>();
            if (type.IsNested)
            {
                path.AddRange(class_name.Split(new char[] { '+' }));
            }
            else
            {
                path.Add(class_name);
            }
            return path;
        }
         if (type.Namespace != null)
         {
            path.AddRange(type.Namespace.Split(new char[] { '.' }));
         }
        public static void LoadCSTable(RealStatePtr L, Type type)
        {
            int oldTop = LuaAPI.lua_gettop(L);
            if (0 != LuaAPI.xlua_getglobal(L, "CS"))
            {
                throw new Exception("call xlua_getglobal fail!");
            }
         string class_name = type.ToString().Substring(type.Namespace == null ? 0 : type.Namespace.Length + 1);
            List<string> path = getPathOfType(type);
         if (type.IsNested)
         {
            path.AddRange(class_name.Split(new char[] { '+' }));
         }
         else
         {
            path.Add(class_name);
         }
         return path;
      }
            for (int i = 0; i < path.Count; ++i)
            {
                LuaAPI.xlua_pushasciistring(L, path[i]);
                if (0 != LuaAPI.xlua_pgettable(L, -2))
                {
                    LuaAPI.lua_settop(L, oldTop);
                    LuaAPI.lua_pushnil(L);
                    return;
                }
                if (!LuaAPI.lua_istable(L, -1) && i < path.Count - 1)
                {
                    LuaAPI.lua_settop(L, oldTop);
                    LuaAPI.lua_pushnil(L);
                    return;
                }
                LuaAPI.lua_remove(L, -2);
            }
        }
      public static void LoadCSTable(RealStatePtr L, Type type)
      {
         int oldTop = LuaAPI.lua_gettop(L);
         if (0 != LuaAPI.xlua_getglobal(L, "CS"))
         {
            throw new Exception("call xlua_getglobal fail!");
         }
        public static void SetCSTable(RealStatePtr L, Type type, int cls_table)
        {
            int oldTop = LuaAPI.lua_gettop(L);
            cls_table = abs_idx(oldTop, cls_table);
            if (0 != LuaAPI.xlua_getglobal(L, "CS"))
            {
                throw new Exception("call xlua_getglobal fail!");
            }
         List<string> path = getPathOfType(type);
            List<string> path = getPathOfType(type);
         for (int i = 0; i < path.Count; ++i)
         {
            LuaAPI.xlua_pushasciistring(L, path[i]);
            if (0 != LuaAPI.xlua_pgettable(L, -2))
            {
               LuaAPI.lua_settop(L, oldTop);
               LuaAPI.lua_pushnil(L);
               return;
            }
            if (!LuaAPI.lua_istable(L, -1) && i < path.Count - 1)
            {
               LuaAPI.lua_settop(L, oldTop);
               LuaAPI.lua_pushnil(L);
               return;
            }
            LuaAPI.lua_remove(L, -2);
         }
      }
            for (int i = 0; i < path.Count - 1; ++i)
            {
                LuaAPI.xlua_pushasciistring(L, path[i]);
                if (0 != LuaAPI.xlua_pgettable(L, -2))
                {
                    LuaAPI.lua_settop(L, oldTop);
                    throw new Exception("SetCSTable for [" + type + "] error: " + LuaAPI.lua_tostring(L, -1));
                }
                if (LuaAPI.lua_isnil(L, -1))
                {
                    LuaAPI.lua_pop(L, 1);
                    LuaAPI.lua_createtable(L, 0, 0);
                    LuaAPI.xlua_pushasciistring(L, path[i]);
                    LuaAPI.lua_pushvalue(L, -2);
                    LuaAPI.lua_rawset(L, -4);
                }
                else if (!LuaAPI.lua_istable(L, -1))
                {
                    LuaAPI.lua_settop(L, oldTop);
                    throw new Exception("SetCSTable for [" + type + "] error: ancestors is not a table!");
                }
                LuaAPI.lua_remove(L, -2);
            }
      public static void SetCSTable(RealStatePtr L, Type type, int cls_table)
      {
         int oldTop = LuaAPI.lua_gettop(L);
         cls_table = abs_idx(oldTop, cls_table);
         if (0 != LuaAPI.xlua_getglobal(L, "CS"))
         {
            throw new Exception("call xlua_getglobal fail!");
         }
            LuaAPI.xlua_pushasciistring(L, path[path.Count -1]);
            LuaAPI.lua_pushvalue(L, cls_table);
            LuaAPI.lua_rawset(L, -3);
            LuaAPI.lua_pop(L, 1);
        }
         List<string> path = getPathOfType(type);
        public const string LuaIndexsFieldName = "LuaIndexs";
         for (int i = 0; i < path.Count - 1; ++i)
         {
            LuaAPI.xlua_pushasciistring(L, path[i]);
            if (0 != LuaAPI.xlua_pgettable(L, -2))
            {
               LuaAPI.lua_settop(L, oldTop);
               throw new Exception("SetCSTable for [" + type + "] error: " + LuaAPI.lua_tostring(L, -1));
            }
            if (LuaAPI.lua_isnil(L, -1))
            {
               LuaAPI.lua_pop(L, 1);
               LuaAPI.lua_createtable(L, 0, 0);
               LuaAPI.xlua_pushasciistring(L, path[i]);
               LuaAPI.lua_pushvalue(L, -2);
               LuaAPI.lua_rawset(L, -4);
            }
            else if (!LuaAPI.lua_istable(L, -1))
            {
               LuaAPI.lua_settop(L, oldTop);
               throw new Exception("SetCSTable for [" + type + "] error: ancestors is not a table!");
            }
            LuaAPI.lua_remove(L, -2);
         }
        public const string LuaNewIndexsFieldName = "LuaNewIndexs";
         LuaAPI.xlua_pushasciistring(L, path[path.Count - 1]);
         LuaAPI.lua_pushvalue(L, cls_table);
         LuaAPI.lua_rawset(L, -3);
         LuaAPI.lua_pop(L, 1);
        public const string LuaClassIndexsFieldName = "LuaClassIndexs";
         LuaAPI.xlua_getglobal(L, "CS");
         ObjectTranslatorPool.Instance.Find(L).PushAny(L, type);
         LuaAPI.lua_pushvalue(L, cls_table);
         LuaAPI.lua_rawset(L, -3);
         LuaAPI.lua_pop(L, 1);
      }
        public const string LuaClassNewIndexsFieldName = "LuaClassNewIndexs";
      public const string LuaIndexsFieldName = "LuaIndexs";
        public static bool IsParamsMatch(MethodInfo delegateMethod, MethodInfo bridgeMethod)
        {
            if (delegateMethod == null || bridgeMethod == null)
            {
                return false;
            }
            if (delegateMethod.ReturnType != bridgeMethod.ReturnType)
            {
                return false;
            }
            ParameterInfo[] delegateParams = delegateMethod.GetParameters();
            ParameterInfo[] bridgeParams = bridgeMethod.GetParameters();
            if (delegateParams.Length != bridgeParams.Length)
            {
                return false;
            }
      public const string LuaNewIndexsFieldName = "LuaNewIndexs";
            for (int i = 0; i < delegateParams.Length; i++)
            {
                if (delegateParams[i].ParameterType != bridgeParams[i].ParameterType || delegateParams[i].IsOut != bridgeParams[i].IsOut)
                {
                    return false;
                }
            }
      public const string LuaClassIndexsFieldName = "LuaClassIndexs";
            return true;
        }
      public const string LuaClassNewIndexsFieldName = "LuaClassNewIndexs";
        public static bool IsSupportedMethod(MethodInfo method)
        {
            if (!method.ContainsGenericParameters)
                return true;
            var methodParameters = method.GetParameters();
            var returnType = method.ReturnType;
            var hasValidGenericParameter = false;
            var returnTypeValid = !returnType.IsGenericParameter;
            for (var i = 0; i < methodParameters.Length; i++)
            {
                var parameterType = methodParameters[i].ParameterType;
                if (parameterType.IsGenericParameter)
                {
                    var parameterConstraints = parameterType.GetGenericParameterConstraints();
                    if (parameterConstraints.Length == 0) return false;
                    foreach (var parameterConstraint in parameterConstraints)
                    {
                        if (!parameterConstraint.IsClass() || (parameterConstraint == typeof(ValueType)))
                            return false;
                    }
                    hasValidGenericParameter = true;
                    if (!returnTypeValid)
                    {
                        if (parameterType == returnType)
                        {
                            returnTypeValid = true;
                        }
                    }
                }
            }
            return hasValidGenericParameter && returnTypeValid;
        }
      public static bool IsParamsMatch(MethodInfo delegateMethod, MethodInfo bridgeMethod)
      {
         if (delegateMethod == null || bridgeMethod == null)
         {
            return false;
         }
         if (delegateMethod.ReturnType != bridgeMethod.ReturnType)
         {
            return false;
         }
         ParameterInfo[] delegateParams = delegateMethod.GetParameters();
         ParameterInfo[] bridgeParams = bridgeMethod.GetParameters();
         if (delegateParams.Length != bridgeParams.Length)
         {
            return false;
         }
        public static MethodInfo MakeGenericMethodWithConstraints(MethodInfo method)
        {
            try
            {
                var genericArguments = method.GetGenericArguments();
                var constraintedArgumentTypes = new Type[genericArguments.Length];
                for (var i = 0; i < genericArguments.Length; i++)
                {
                    var argumentType = genericArguments[i];
                    var parameterConstraints = argumentType.GetGenericParameterConstraints();
                    constraintedArgumentTypes[i] = parameterConstraints[0];
                }
                return method.MakeGenericMethod(constraintedArgumentTypes);
            }
            catch (Exception)
            {
                return null;
            }
        }
         for (int i = 0; i < delegateParams.Length; i++)
         {
            if (delegateParams[i].ParameterType != bridgeParams[i].ParameterType || delegateParams[i].IsOut != bridgeParams[i].IsOut)
            {
               return false;
            }
         }
        private static Type getExtendedType(MethodInfo method)
        {
            var type = method.GetParameters()[0].ParameterType;
            if (!type.IsGenericParameter)
                return type;
            var parameterConstraints = type.GetGenericParameterConstraints();
            if (parameterConstraints.Length == 0)
                throw new InvalidOperationException();
         return true;
      }
            var firstParameterConstraint = parameterConstraints[0];
            if (!firstParameterConstraint.IsClass())
                throw new InvalidOperationException();
            return firstParameterConstraint;
        }
      public static bool IsSupportedMethod(MethodInfo method)
      {
         if (!method.ContainsGenericParameters)
            return true;
         var methodParameters = method.GetParameters();
         var returnType = method.ReturnType;
         var hasValidGenericParameter = false;
         var returnTypeValid = !returnType.IsGenericParameter;
         for (var i = 0; i < methodParameters.Length; i++)
         {
            var parameterType = methodParameters[i].ParameterType;
            if (parameterType.IsGenericParameter)
            {
               var parameterConstraints = parameterType.GetGenericParameterConstraints();
               if (parameterConstraints.Length == 0) return false;
               foreach (var parameterConstraint in parameterConstraints)
               {
                  if (!parameterConstraint.IsClass() || (parameterConstraint == typeof(ValueType)))
                     return false;
               }
               hasValidGenericParameter = true;
               if (!returnTypeValid)
               {
                  if (parameterType == returnType)
                  {
                     returnTypeValid = true;
                  }
               }
            }
         }
         return hasValidGenericParameter && returnTypeValid;
      }
        public static bool IsStaticPInvokeCSFunction(LuaCSFunction csFunction)
        {
      public static MethodInfo MakeGenericMethodWithConstraints(MethodInfo method)
      {
         try
         {
            var genericArguments = method.GetGenericArguments();
            var constraintedArgumentTypes = new Type[genericArguments.Length];
            for (var i = 0; i < genericArguments.Length; i++)
            {
               var argumentType = genericArguments[i];
               var parameterConstraints = argumentType.GetGenericParameterConstraints();
               constraintedArgumentTypes[i] = parameterConstraints[0];
            }
            return method.MakeGenericMethod(constraintedArgumentTypes);
         }
         catch (Exception)
         {
            return null;
         }
      }
      private static Type getExtendedType(MethodInfo method)
      {
         var type = method.GetParameters()[0].ParameterType;
         if (!type.IsGenericParameter)
            return type;
         var parameterConstraints = type.GetGenericParameterConstraints();
         if (parameterConstraints.Length == 0)
            throw new InvalidOperationException();
         var firstParameterConstraint = parameterConstraints[0];
         if (!firstParameterConstraint.IsClass())
            throw new InvalidOperationException();
         return firstParameterConstraint;
      }
      public static bool IsStaticPInvokeCSFunction(LuaCSFunction csFunction)
      {
#if UNITY_WSA && !UNITY_EDITOR
            return csFunction.GetMethodInfo().IsStatic && csFunction.GetMethodInfo().GetCustomAttribute<MonoPInvokeCallbackAttribute>() != null;
#else
            return csFunction.Method.IsStatic && Attribute.IsDefined(csFunction.Method, typeof(MonoPInvokeCallbackAttribute));
         return csFunction.Method.IsStatic && Attribute.IsDefined(csFunction.Method, typeof(MonoPInvokeCallbackAttribute));
#endif
        }
      }
        public static bool IsPublic(Type type)
        {
            if (type.IsNested)
            {
                if (!type.IsNestedPublic()) return false;
                return IsPublic(type.DeclaringType);
            }
            if (type.IsGenericType())
            {
                var gas = type.GetGenericArguments();
                for(int i = 0; i < gas.Length; i++)
                {
                    if (!IsPublic(gas[i]))
                    {
                        return false;
                    }
                }
            }
            return type.IsPublic();
        }
    }
      public static bool IsPublic(Type type)
      {
         if (type.IsNested)
         {
            if (!type.IsNestedPublic()) return false;
            return IsPublic(type.DeclaringType);
         }
         if (type.IsGenericType())
         {
            var gas = type.GetGenericArguments();
            for (int i = 0; i < gas.Length; i++)
            {
               if (!IsPublic(gas[i]))
               {
                  return false;
               }
            }
         }
         return type.IsPublic();
      }
   }
}