context: using System;
  using System.Runtime.InteropServices;
  
  namespace LuaInterface
  {
  #pragma warning disable 414
      public class MonoPInvokeCallbackAttribute : System.Attribute
      {
          private Type type;
          public MonoPInvokeCallbackAttribute(Type t)
          {
              type = t;
          }
      }
  #pragma warning restore 414
  
      public enum LuaTypes : int
      {
          LUA_TNONE = -1,
          LUA_TNIL = 0,
          LUA_TBOOLEAN = 1,
          LUA_TLIGHTUSERDATA = 2,
          LUA_TNUMBER = 3,
          LUA_TSTRING = 4,
          LUA_TTABLE = 5,
          LUA_TFUNCTION = 6,
          LUA_TUSERDATA = 7,
          LUA_TTHREAD = 8,
      }
  
      public enum LuaGCOptions
      {
          LUA_GCSTOP = 0,
          LUA_GCRESTART = 1,
          LUA_GCCOLLECT = 2,
          LUA_GCCOUNT = 3,
          LUA_GCCOUNTB = 4,
          LUA_GCSTEP = 5,
          LUA_GCSETPAUSE = 6,
          LUA_GCSETSTEPMUL = 7,
      }
  
      public enum LuaThreadStatus : int
      {
          LUA_YIELD = 1,
          LUA_ERRRUN = 2,
          LUA_ERRSYNTAX = 3,
          LUA_ERRMEM = 4,
          LUA_ERRERR = 5,
      }
  
      public sealed class LuaIndexes
      {
  #if LUA_5_3
          // for lua5.3
          public static int LUA_REGISTRYINDEX = -1000000 - 1000;
  #else
          // for lua5.1 or luajit
          public static int LUA_REGISTRYINDEX = -10000;
          public static int LUA_GLOBALSINDEX = -10002;
  #endif
      }
  
      [StructLayout(LayoutKind.Sequential)]
      public struct ReaderInfo
      {
          public String chunkData;
          public bool finished;
      }
  
  #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
      public delegate int LuaCSFunction(IntPtr luaState);
  #else
  	public delegate int LuaCSFunction(IntPtr luaState);
  #endif
  
      public delegate string LuaChunkReader(IntPtr luaState, ref ReaderInfo data, ref uint size);
  
      public delegate int LuaFunctionCallback(IntPtr luaState);
      public class LuaDLL
      {
          public static int LUA_MULTRET = -1;
  #if UNITY_IPHONE && !UNITY_EDITOR
  		const string LUADLL = "__Internal";
  #else
          const string LUADLL = "slua";
  #endif
          //pdc
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
          public static extern int luaopen_protobuf_c(IntPtr luaState);
  
          //lpeg
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
          public static extern int luaopen_lpeg(IntPtr luaState);
  
          //cjson
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
          public static extern int luaopen_cjson(IntPtr luaState);
  
          //lua socket
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
          public static extern int luaopen_socket_core(IntPtr luaState);
  
          //lua socket mime
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
          public static extern int luaopen_mime_core(IntPtr luaState);
  
          //sproto
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
          public static extern int luaopen_sproto_core(IntPtr luaState);
  
          //sqlite
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
          public static extern int luaopen_lsqlite3(IntPtr luaState);
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern void luaS_openextlibs(IntPtr L);
  
          // Thread Funcs
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern int lua_tothread(IntPtr L, int index);
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern void lua_xmove(IntPtr from, IntPtr to, int n);
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern IntPtr lua_newthread(IntPtr L);
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern int lua_status(IntPtr L);
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern int lua_pushthread(IntPtr L);
  
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern int lua_gc(IntPtr luaState, LuaGCOptions what, int data);
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern IntPtr lua_typename(IntPtr luaState, int type);
          public static string lua_typenamestr(IntPtr luaState, LuaTypes type)
          {
              IntPtr p = lua_typename(luaState, (int)type);
              return Marshal.PtrToStringAnsi(p);
          }
          public static string luaL_typename(IntPtr luaState, int stackPos)
          {
              return LuaDLL.lua_typenamestr(luaState, LuaDLL.lua_type(luaState, stackPos));
          }
  
          public static bool lua_isfunction(IntPtr luaState, int stackPos)
          {
              return lua_type(luaState, stackPos) == LuaTypes.LUA_TFUNCTION;
          }
  
          public static bool lua_islightuserdata(IntPtr luaState, int stackPos)
          {
              return lua_type(luaState, stackPos) == LuaTypes.LUA_TLIGHTUSERDATA;
          }
  
          public static bool lua_istable(IntPtr luaState, int stackPos)
          {
              return lua_type(luaState, stackPos) == LuaTypes.LUA_TTABLE;
          }
  
          public static bool lua_isthread(IntPtr luaState, int stackPos)
          {
              return lua_type(luaState, stackPos) == LuaTypes.LUA_TTHREAD;
          }
  
          [Obsolete]
          public static void luaL_error(IntPtr luaState, string message)
          {
              //LuaDLL.lua_pushstring(luaState, message);
              //LuaDLL.lua_error(luaState);
          }
  
          [Obsolete]
          public static void luaL_error(IntPtr luaState, string fmt, params object[] args)
          {
              //string str = string.Format(fmt, args);
              //luaL_error(luaState, str);
          }
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern string luaL_gsub(IntPtr luaState, string str, string pattern, string replacement);
  
  
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern int lua_isuserdata(IntPtr luaState, int stackPos);
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern int lua_rawequal(IntPtr luaState, int stackPos1, int stackPos2);
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern void lua_setfield(IntPtr luaState, int stackPos, string name);
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern int luaL_callmeta(IntPtr luaState, int stackPos, string name);
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern IntPtr luaL_newstate();
  
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern void lua_close(IntPtr luaState);
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern void luaL_openlibs(IntPtr luaState);
  
  
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern int luaL_loadstring(IntPtr luaState, string chunk);
          public static int luaL_dostring(IntPtr luaState, string chunk)
          {
              int result = LuaDLL.luaL_loadstring(luaState, chunk);
              if (result != 0)
                  return result;
  
              return LuaDLL.lua_pcall(luaState, 0, -1, 0);
          }
          public static int lua_dostring(IntPtr luaState, string chunk)
          {
              return LuaDLL.luaL_dostring(luaState, chunk);
          }
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern void lua_createtable(IntPtr luaState, int narr, int nrec);
          public static void lua_newtable(IntPtr luaState)
          {
              LuaDLL.lua_createtable(luaState, 0, 0);
          }
  
  #if LUA_5_3
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern void lua_getglobal(IntPtr luaState, string name);
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern void lua_setglobal(IntPtr luaState, string name);
  
          public static void lua_insert(IntPtr luaState, int newTop)
          {
              lua_rotate(luaState, newTop, 1);
          }
  
          public static void lua_pushglobaltable(IntPtr l)
          {
              lua_rawgeti(l, LuaIndexes.LUA_REGISTRYINDEX, 2); 
          }
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern int lua_rotate(IntPtr luaState, int index, int n);
  
          public static int lua_rawlen(IntPtr luaState, int stackPos)
  		{
  			return LuaDLLWrapper.luaS_rawlen(luaState, stackPos);
  		}
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern int luaL_loadbufferx(IntPtr luaState, byte[] buff, int size, string name, IntPtr x);
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern int lua_callk(IntPtr luaState, int nArgs, int nResults,int ctx,IntPtr k);
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern int lua_pcallk(IntPtr luaState, int nArgs, int nResults, int errfunc,int ctx,IntPtr k);
  
  		[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
  		public static extern int luaS_pcall(IntPtr luaState, int nArgs, int nResults, int errfunc);
  		
  		public static int lua_call(IntPtr luaState, int nArgs, int nResults)
          {
              return lua_callk(luaState, nArgs, nResults, 0, IntPtr.Zero);
          }
  
          public static int lua_pcall(IntPtr luaState, int nArgs, int nResults, int errfunc)
          {
  			return luaS_pcall(luaState, nArgs, nResults, errfunc);
          }
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern double lua_tonumberx(IntPtr luaState, int index, IntPtr x);
          public static double lua_tonumber(IntPtr luaState, int index)
          {
              return lua_tonumberx(luaState, index, IntPtr.Zero);
          }        
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern Int64 lua_tointegerx(IntPtr luaState, int index,IntPtr x);
          public static int lua_tointeger(IntPtr luaState, int index)
          {
              return (int)lua_tointegerx(luaState, index, IntPtr.Zero);
          }
  
  
          public static int luaL_loadbuffer(IntPtr luaState, byte[] buff, int size, string name)
          {
              return luaL_loadbufferx(luaState, buff, size, name, IntPtr.Zero);
          }
  
          public static void lua_remove(IntPtr l, int idx)
          {
              lua_rotate(l, (idx), -1);
              lua_pop(l, 1);
          }
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern void lua_rawgeti(IntPtr luaState, int tableIndex, Int64 index);
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern void lua_rawseti(IntPtr luaState, int tableIndex, Int64 index);
  
          [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
          public static extern void lua_pushinteger(IntPtr luaState, Int64 i);
  
          public static Int64 luaL_checkinteger(IntPtr luaState, int stackPos) {
  			luaL_checktype(luaState, stackPos, LuaTypes.LUA_TNUMBER);
  			return lua_tointegerx(luaState, stackPos, IntPtr.Zero);
  		}
  
  		[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
  		public static extern int luaS_yield(IntPtr luaState,int nrets);
  
  		public static int lua_yield(IntPtr luaState,int nrets) {
  			return luaS_yield(luaState,nrets);
  		}
  
  
  		[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
  		public static extern int lua_resume(IntPtr L, IntPtr from, int narg);
  
  		public static void lua_replace(IntPtr luaState, int index) {
  			lua_copy(luaState, -1, (index));
  			lua_pop(luaState, 1);
  		}
  
  
gt: 		[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]