summaryrefslogtreecommitdiff
path: root/ThirdParty/tolua_runtime/tolua.c
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2021-11-08 01:17:11 +0800
committerchai <chaifix@163.com>2021-11-08 01:17:11 +0800
commitefce5b6bd5c9d4f8214a71e0f7a7c35751710a4c (patch)
tree0789475ded5c377667165a3ddb047ca6703bcf33 /ThirdParty/tolua_runtime/tolua.c
parented78df90944bbe6b7de7308bda2bf3a7f1bc3de6 (diff)
+ tolua
+ lpeg
Diffstat (limited to 'ThirdParty/tolua_runtime/tolua.c')
-rw-r--r--ThirdParty/tolua_runtime/tolua.c2745
1 files changed, 2745 insertions, 0 deletions
diff --git a/ThirdParty/tolua_runtime/tolua.c b/ThirdParty/tolua_runtime/tolua.c
new file mode 100644
index 0000000..af5ce7b
--- /dev/null
+++ b/ThirdParty/tolua_runtime/tolua.c
@@ -0,0 +1,2745 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2015-2016 topameng(topameng@qq.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include <string.h>
+#if !defined __APPLE__
+#include <malloc.h>
+#endif
+#include <stdbool.h>
+#include <math.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "lua.h"
+#include "lualib.h"
+#include "lauxlib.h"
+#include "tolua.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <time.h>
+#include <sys/time.h>
+#endif
+
+int toluaflags = FLAG_INDEX_ERROR;
+static int tag = 0;
+static int gettag = 0;
+static int settag = 0;
+static int vptr = 1;
+
+/*---------------------------tolua extend functions--------------------------------*/
+LUALIB_API void* tolua_tag()
+{
+ return &tag;
+}
+
+LUALIB_API void tolua_newudata(lua_State *L, int val)
+{
+ int* pointer = (int*)lua_newuserdata(L, sizeof(int));
+ lua_pushvalue(L, TOLUA_NOPEER);
+ lua_setfenv(L, -2);
+ *pointer = val;
+}
+
+LUALIB_API int tolua_rawnetobj(lua_State *L, int index)
+{
+ int* udata = (int*)lua_touserdata(L, index);
+
+ if (udata != NULL)
+ {
+ return *udata;
+ }
+ else if (lua_istable(L, index))
+ {
+ lua_pushvalue(L, index);
+ lua_pushlightuserdata(L, &vptr);
+ lua_rawget(L, -2);
+
+ if (lua_isuserdata(L, -1))
+ {
+ lua_replace(L, index);
+ udata = (int*)lua_touserdata(L, index);
+
+ if (udata != NULL)
+ {
+ return *udata;
+ }
+ }
+ else
+ {
+ lua_pop(L, 1);
+ }
+ }
+
+ return -1;
+}
+
+LUALIB_API char* tolua_tocbuffer(const char *csBuffer, int sz)
+{
+ char* buffer = (char*)malloc(sz+1);
+ memcpy(buffer, csBuffer, sz);
+ buffer[sz] = '\0';
+ return buffer;
+}
+
+LUALIB_API void tolua_freebuffer(void* buffer)
+{
+ free(buffer);
+}
+
+LUALIB_API void tolua_getvec2(lua_State *L, int pos, float* x, float* y)
+{
+ lua_getref(L, LUA_RIDX_UNPACKVEC2);
+ lua_pushvalue(L, pos);
+ lua_call(L, 1, 2);
+ *x = (float)lua_tonumber(L, -2);
+ *y = (float)lua_tonumber(L, -1);
+ lua_pop(L, 2);
+}
+
+LUALIB_API void tolua_getvec3(lua_State *L, int pos, float* x, float* y, float* z)
+{
+ lua_getref(L, LUA_RIDX_UNPACKVEC3);
+ lua_pushvalue(L, pos);
+ lua_call(L, 1, 3);
+ *x = (float)lua_tonumber(L, -3);
+ *y = (float)lua_tonumber(L, -2);
+ *z = (float)lua_tonumber(L, -1);
+ lua_pop(L, 3);
+}
+
+LUALIB_API void tolua_getvec4(lua_State *L, int pos, float* x, float* y, float* z, float* w)
+{
+ lua_getref(L, LUA_RIDX_UNPACKVEC4);
+ lua_pushvalue(L, pos);
+ lua_call(L, 1, 4);
+ *x = (float)lua_tonumber(L, -4);
+ *y = (float)lua_tonumber(L, -3);
+ *z = (float)lua_tonumber(L, -2);
+ *w = (float)lua_tonumber(L, -1);
+ lua_pop(L, 4);
+}
+
+LUALIB_API void tolua_getquat(lua_State *L, int pos, float* x, float* y, float* z, float* w)
+{
+ lua_getref(L, LUA_RIDX_UNPACKQUAT);
+ lua_pushvalue(L, pos);
+ lua_call(L, 1, 4);
+ *x = (float)lua_tonumber(L, -4);
+ *y = (float)lua_tonumber(L, -3);
+ *z = (float)lua_tonumber(L, -2);
+ *w = (float)lua_tonumber(L, -1);
+ lua_pop(L, 4);
+}
+
+LUALIB_API void tolua_getclr(lua_State *L, int pos, float* r, float* g, float* b, float* a)
+{
+ lua_getref(L, LUA_RIDX_UNPACKCLR);
+ lua_pushvalue(L, pos);
+ lua_call(L, 1, 4);
+ *r = (float)lua_tonumber(L, -4);
+ *g = (float)lua_tonumber(L, -3);
+ *b = (float)lua_tonumber(L, -2);
+ *a = (float)lua_tonumber(L, -1);
+ lua_pop(L, 4);
+}
+
+LUALIB_API int tolua_getlayermask(lua_State *L, int pos)
+{
+ if (lua_isnumber(L, pos))
+ {
+ return (int)lua_tointeger(L, pos);
+ }
+
+ lua_getref(L, LUA_RIDX_UNPACKLAYERMASK);
+ lua_pushvalue(L, pos);
+ lua_call(L, 1, 1);
+ int mask = (int)lua_tointeger(L, -1);
+ lua_pop(L, 1);
+ return mask;
+}
+
+LUALIB_API void tolua_pushvec2(lua_State *L, float x, float y)
+{
+ lua_getref(L, LUA_RIDX_PACKVEC2);
+ lua_pushnumber(L, x);
+ lua_pushnumber(L, y);
+ lua_call(L, 2, 1);
+}
+
+LUALIB_API void tolua_pushvec3(lua_State *L, float x, float y, float z)
+{
+ lua_getref(L, LUA_RIDX_PACKVEC3);
+ lua_pushnumber(L, x);
+ lua_pushnumber(L, y);
+ lua_pushnumber(L, z);
+ lua_call(L, 3, 1);
+}
+
+LUALIB_API void tolua_pushvec4(lua_State *L, float x, float y, float z, float w)
+{
+ lua_getref(L, LUA_RIDX_PACKVEC4);
+ lua_pushnumber(L, x);
+ lua_pushnumber(L, y);
+ lua_pushnumber(L, z);
+ lua_pushnumber(L, w);
+ lua_call(L, 4, 1);
+}
+
+LUALIB_API void tolua_pushquat(lua_State *L, float x, float y, float z, float w)
+{
+ lua_getref(L, LUA_RIDX_PACKQUAT);
+ lua_pushnumber(L, x);
+ lua_pushnumber(L, y);
+ lua_pushnumber(L, z);
+ lua_pushnumber(L, w);
+ lua_call(L, 4, 1);
+}
+
+LUALIB_API void tolua_pushclr(lua_State *L, float r, float g, float b, float a)
+{
+ lua_getref(L, LUA_RIDX_PACKCLR);
+ lua_pushnumber(L, r);
+ lua_pushnumber(L, g);
+ lua_pushnumber(L, b);
+ lua_pushnumber(L, a);
+ lua_call(L, 4, 1);
+}
+
+LUALIB_API void tolua_pushlayermask(lua_State *L, int mask)
+{
+ lua_getref(L, LUA_RIDX_PACKLAYERMASK);
+ lua_pushnumber(L, mask);
+ lua_call(L, 1, 1);
+}
+
+
+LUA_API const char* tolua_tolstring(lua_State *L, int index, int* len)
+{
+ size_t sz;
+ const char *ret = lua_tolstring(L, index, &sz);
+ *len = (int)sz;
+ return ret;
+}
+
+LUA_API void tolua_pushlstring(lua_State *L, const char *s, int l)
+{
+ lua_pushlstring(L, s, (size_t)l);
+}
+
+LUA_API void* tolua_newuserdata(lua_State *L, int sz)
+{
+ return lua_newuserdata(L, (size_t)sz);
+}
+
+LUA_API int tolua_objlen(lua_State *L, int idx)
+{
+ size_t len = lua_objlen(L, idx);
+ return (int)len;
+}
+
+LUA_API bool tolua_toboolean(lua_State *L, int idx)
+{
+ int value = lua_toboolean(L, idx);
+ return value == 0 ? false : true;
+}
+
+LUA_API int32_t tolua_tointeger(lua_State *L, int idx)
+{
+ return (int32_t)lua_tointeger(L, idx);
+}
+
+LUALIB_API int tolua_loadbuffer(lua_State *L, const char *buff, int sz, const char *name)
+{
+ return luaL_loadbuffer(L, buff, (size_t)sz, name);
+}
+
+static int _lua_getfield(lua_State *L)
+{
+ const char *name = lua_tostring(L, 2);
+ lua_getfield(L, 1, name);
+ return 1;
+}
+
+LUA_API int tolua_getfield(lua_State *L, int idx, const char *field)
+{
+ idx = abs_index(L, idx);
+ lua_pushcfunction(L, _lua_getfield);
+ lua_pushvalue(L, idx);
+ lua_pushstring(L, field);
+ return lua_pcall(L, 2, 1, 0);
+}
+
+static int _lua_setfield(lua_State *L)
+{
+ const char *name = lua_tostring(L, 2);
+ lua_setfield(L, 1, name);
+ return 0;
+}
+
+LUA_API int tolua_setfield(lua_State *L, int idx, const char *key)
+{
+ int top = lua_gettop(L);
+ idx = abs_index(L, idx);
+ lua_pushcfunction(L, _lua_setfield);
+ lua_pushvalue(L, idx);
+ lua_pushstring(L, key);
+ lua_pushvalue(L, top);
+ lua_remove(L, top);
+ return lua_pcall(L, 3, -1, 0);
+}
+
+static int _lua_gettable(lua_State *L)
+{
+ lua_gettable(L, 1);
+ return 1;
+}
+
+LUA_API int tolua_gettable(lua_State *L, int idx)
+{
+ int top = lua_gettop(L);
+ idx = abs_index(L, idx);
+ lua_pushcfunction(L, _lua_gettable);
+ lua_pushvalue(L, idx);
+ lua_pushvalue(L, top);
+ lua_remove(L, top);
+ return lua_pcall(L, 2, -1, 0);
+}
+
+static int _lua_settable(lua_State *L)
+{
+ lua_settable(L, 1);
+ return 0;
+}
+
+LUA_API int tolua_settable(lua_State *L, int idx)
+{
+ int top = lua_gettop(L);
+ idx = abs_index(L, idx);
+ lua_pushcfunction(L, _lua_settable);
+ lua_pushvalue(L, idx);
+ lua_pushvalue(L, top - 1);
+ lua_pushvalue(L, top);
+ lua_remove(L, top);
+ lua_remove(L, top - 1);
+ return lua_pcall(L, 3, -1, 0);
+}
+
+static int tolua_closure(lua_State *L)
+{
+ lua_CFunction fn = (lua_CFunction)lua_tocfunction(L, lua_upvalueindex(2));
+ int r = fn(L);
+
+ if (lua_toboolean(L, lua_upvalueindex(1)))
+ {
+ lua_pushboolean(L, 0);
+ lua_replace(L, lua_upvalueindex(1));
+ return lua_error(L);
+ }
+
+ return r;
+}
+
+//hack for luac, 避免luac error破坏包裹c#函数的异常块(luajit采用的是类似c++异常)
+LUA_API int tolua_pushcfunction(lua_State *L, lua_CFunction fn)
+{
+ lua_pushboolean(L, 0);
+ lua_pushcfunction(L, fn);
+ lua_pushcclosure(L, tolua_closure, 2);
+ return 0;
+}
+
+static int tolua_pusherror(lua_State *L, const char *fmt, ...)
+{
+ va_list argp;
+ va_start(argp, fmt);
+ luaL_where(L, 1);
+ lua_pushvfstring(L, fmt, argp);
+ va_end(argp);
+ lua_concat(L, 2);
+ return 1;
+}
+
+LUALIB_API int tolua_argerror(lua_State *L, int narg, const char *extramsg)
+{
+ lua_Debug ar;
+
+ if (!lua_getstack(L, 0, &ar)) /* no stack frame? */
+ {
+ return tolua_pusherror(L, "bad argument #%d (%s)", narg, extramsg);
+ }
+
+ lua_getinfo(L, "n", &ar);
+
+ if (strcmp(ar.namewhat, "method") == 0)
+ {
+ narg--; /* do not count `self' */
+
+ if (narg == 0) /* error is in the self argument itself? */
+ {
+ return tolua_pusherror(L, "calling " LUA_QS " on bad self (%s)", ar.name, extramsg);
+ }
+ }
+
+ if (ar.name == NULL)
+ {
+ ar.name = "?";
+ }
+
+ return tolua_pusherror(L, "bad argument #%d to " LUA_QS " (%s)", narg, ar.name, extramsg);
+}
+
+LUALIB_API int tolua_error(lua_State *L, const char *msg)
+{
+ lua_pushboolean(L, 1);
+ lua_replace(L, lua_upvalueindex(1));
+ lua_pushstring(L, msg);
+ return 1;
+}
+
+LUALIB_API int tolua_getn(lua_State *L, int i)
+{
+ return tolua_objlen(L, i);
+}
+
+LUALIB_API int tolua_strlen(const char *str)
+{
+ if (str == NULL)
+ {
+ return 0;
+ }
+
+ int len = (int)strlen(str);
+ return len;
+}
+
+static bool _preload(lua_State *L)
+{
+ lua_settop(L, 2);
+ lua_getmetatable(L, 1);
+ lua_pushstring(L, ".name"); //stack: t key mt ".name"
+ lua_rawget(L, -2); //stack: t key mt space
+
+ if (!lua_isnil(L, -1)) //stack: t key mt space
+ {
+ lua_getref(L, LUA_RIDX_PRELOAD); //stack: t key mt space preload
+ lua_pushvalue(L, -2); //stack: t key mt space preload space
+ lua_pushstring(L, "."); //stack: t key mt space preload space.
+ lua_pushvalue(L, 2); //stack: t key mt space preload space.key
+ lua_concat(L, 3); //stack: t key mt space preload key1
+ lua_pushvalue(L, -1); //stack: t key mt space preload key1 key1
+ lua_rawget(L, -3); //stack: t key mt space preload key1 value
+
+ if (!lua_isnil(L, -1))
+ {
+ lua_pop(L, 1); //stack: t key mt space preload key1
+ lua_getref(L, LUA_RIDX_REQUIRE); //stack: t key mt space preload key1 require
+ lua_pushvalue(L, -2);
+ lua_call(L, 1, 1);
+ return true;
+ }
+ }
+
+ lua_settop(L, 2);
+ return false;
+}
+
+static int class_index_event(lua_State *L)
+{
+ int t = lua_type(L, 1);
+
+ if (t == LUA_TUSERDATA)
+ {
+ lua_getfenv(L,1);
+
+ if (!lua_rawequal(L, -1, TOLUA_NOPEER)) // stack: t k env
+ {
+ while (lua_istable(L, -1)) // stack: t k v mt
+ {
+ lua_pushvalue(L, 2);
+ lua_rawget(L, -2);
+
+ if (!lua_isnil(L, -1))
+ {
+ return 1;
+ }
+
+ lua_pop(L, 1);
+ lua_pushlightuserdata(L, &gettag);
+ lua_rawget(L, -2); //stack: obj key env tget
+
+ if (lua_istable(L, -1))
+ {
+ lua_pushvalue(L, 2); //stack: obj key env tget key
+ lua_rawget(L, -2); //stack: obj key env tget func
+
+ if (lua_isfunction(L, -1))
+ {
+ lua_pushvalue(L, 1);
+ lua_call(L, 1, 1);
+ return 1;
+ }
+
+ lua_pop(L, 1);
+ }
+
+ lua_pop(L, 1);
+
+ if (lua_getmetatable(L, -1) == 0) // stack: t k v mt mt
+ {
+ lua_pushnil(L);
+ }
+
+ lua_remove(L, -2); // stack: t k v mt
+ }
+ };
+
+ lua_settop(L,2);
+ lua_pushvalue(L, 1); // stack: obj key obj
+
+ while (lua_getmetatable(L, -1) != 0)
+ {
+ lua_remove(L, -2); // stack: obj key mt
+
+ if (lua_isnumber(L,2)) // check if key is a numeric value
+ {
+ lua_pushstring(L,".geti");
+ lua_rawget(L,-2); // stack: obj key mt func
+
+ if (lua_isfunction(L,-1))
+ {
+ lua_pushvalue(L,1);
+ lua_pushvalue(L,2);
+ lua_call(L,2,1);
+ return 1;
+ }
+ }
+ else
+ {
+ lua_pushvalue(L, 2); // stack: obj key mt key
+ lua_rawget(L, -2); // stack: obj key mt value
+
+ if (!lua_isnil(L, -1))
+ {
+ return 1;
+ }
+
+ lua_pop(L, 1);
+ lua_pushlightuserdata(L, &gettag);
+ lua_rawget(L, -2); //stack: obj key mt tget
+
+ if (lua_istable(L, -1))
+ {
+ lua_pushvalue(L, 2); //stack: obj key mt tget key
+ lua_rawget(L, -2); //stack: obj key mt tget value
+
+ if (lua_isfunction(L, -1))
+ {
+ lua_pushvalue(L, 1);
+ lua_call(L, 1, 1);
+ return 1;
+ }
+ }
+ }
+
+ lua_settop(L, 3);
+ }
+
+ lua_settop(L, 2);
+ int *udata = (int*)lua_touserdata(L, 1);
+
+ if (*udata == LUA_NULL_USERDATA)
+ {
+ return luaL_error(L, "attemp to index %s on a nil value", lua_tostring(L, 2));
+ }
+
+ if (toluaflags & FLAG_INDEX_ERROR)
+ {
+ return luaL_error(L, "field or property %s does not exist", lua_tostring(L, 2));
+ }
+ }
+ else if(t == LUA_TTABLE)
+ {
+ lua_pushvalue(L,1); //stack: obj key obj
+
+ while (lua_getmetatable(L, -1) != 0) //stack: obj key obj mt
+ {
+ lua_remove(L, -2); // stack: obj key mt
+
+ lua_pushvalue(L, 2); // stack: obj key mt key
+ lua_rawget(L, -2); // stack: obj key mt value
+
+ if (!lua_isnil(L, -1))
+ {
+ if (lua_isfunction(L, -1)) //cache static function
+ {
+ lua_pushvalue(L, 2); // stack: obj key mt value key
+ lua_pushvalue(L, -2); // stack: obj key mt value key value
+ lua_rawset(L, 1);
+ }
+
+ return 1;
+ }
+
+ lua_pop(L, 1);
+ lua_pushlightuserdata(L, &gettag);
+ lua_rawget(L, -2); //stack: obj key mt tget
+
+ if (lua_istable(L, -1))
+ {
+ lua_pushvalue(L, 2); //stack: obj key mt tget key
+ lua_rawget(L, -2); //stack: obj key mt tget value
+
+ if (lua_isfunction(L, -1))
+ {
+ lua_pushvalue(L, 1);
+ lua_call(L, 1, 1);
+ return 1;
+ }
+ }
+
+ lua_settop(L, 3);
+ }
+
+ if (_preload(L))
+ {
+ return 1;
+ }
+
+ if (toluaflags & FLAG_INDEX_ERROR)
+ {
+ return luaL_error(L, "field or property %s does not exist", lua_tostring(L, 2));
+ }
+ }
+
+ lua_pushnil(L);
+ return 1;
+}
+
+static void storeatubox (lua_State *L, int lo)
+{
+ lua_getfenv(L, lo); // stack: t, k, v, _env
+
+ if (lua_rawequal(L, -1, TOLUA_NOPEER))
+ {
+ lua_pop(L, 1);
+ return;
+ //lua_newtable(L); // stack: t, k, v, t
+ //lua_pushvalue(L, -1); // stack: t, k, v, t, t
+ //lua_setfenv(L, lo); // stack: t, k, v, t
+ };
+
+ lua_insert(L, -3);
+ lua_settable(L, -3);
+ lua_pop(L, 1);
+}
+
+static int class_newindex_event(lua_State *L)
+{
+ int t = lua_type(L, 1);
+
+ if (t == LUA_TUSERDATA)
+ {
+ bool useEnv = false;
+ lua_getfenv(L, 1);
+
+ if (!lua_rawequal(L, -1, TOLUA_NOPEER))
+ {
+ useEnv = true;
+
+ while (lua_istable(L, -1)) // stack: t k v mt
+ {
+ lua_pushvalue(L, 2); // stack: t k v mt k
+ lua_rawget(L, -2); // stack: t k v mt value
+
+ if (!lua_isnil(L, -1))
+ {
+ lua_pop(L, 1);
+ lua_insert(L, -3);
+ lua_rawset(L, -3);
+ return 0;
+ }
+
+ lua_pop(L, 1);
+ lua_pushlightuserdata(L, &settag); // stack: t k v mt tset
+ lua_rawget(L, -2);
+
+ if (lua_istable(L, -1))
+ {
+ lua_pushvalue(L, 2); // stack: t k v mt tset k
+ lua_rawget(L, -2);
+
+ if (lua_isfunction(L, -1))
+ {
+ lua_pushvalue(L, 1);
+ lua_pushvalue(L, 3);
+ lua_call(L, 2, 0);
+ return 0;
+ }
+
+ lua_pop(L, 1); // stack: t k v mt tset
+ }
+
+ lua_pop(L, 1); // stack: t k v mt
+
+ if (lua_getmetatable(L, -1) == 0) // stack: t k v mt mt
+ {
+ lua_pushnil(L);
+ }
+
+ lua_remove(L, -2); // stack: t k v mt
+ }
+ }
+
+ lua_settop(L, 3);
+ lua_getmetatable(L,1);
+
+ while (lua_istable(L, -1)) // stack: t k v mt
+ {
+ if (lua_isnumber(L, 2))
+ {
+ lua_pushstring(L,".seti");
+ lua_rawget(L,-2); // stack: obj key mt func
+
+ if (lua_isfunction(L,-1))
+ {
+ lua_pushvalue(L,1);
+ lua_pushvalue(L,2);
+ lua_pushvalue(L,3);
+ lua_call(L,3,0);
+ }
+
+ return 0;
+ }
+ else
+ {
+ lua_pushlightuserdata(L, &settag);
+ lua_rawget(L, -2); // stack: t k v mt tset
+
+ if (lua_istable(L, -1))
+ {
+ lua_pushvalue(L, 2);
+ lua_rawget(L, -2); // stack: t k v mt tset func
+
+ if (lua_isfunction(L, -1))
+ {
+ lua_pushvalue(L, 1);
+ lua_pushvalue(L, 3);
+ lua_call(L, 2, 0);
+ return 0;
+ }
+
+ lua_pop(L, 1); // stack: t k v mt tset
+ }
+
+ lua_pop(L, 1); // stack: t k v mt
+
+ if (lua_getmetatable(L, -1) == 0) // stack: t k v mt mt
+ {
+ lua_pushnil(L);
+ }
+
+ lua_remove(L, -2); // stack: t k v mt
+ }
+ }
+
+ lua_settop(L, 3); // stack: t k v
+ int* udata = (int*)lua_touserdata(L, 1);
+
+ if (*udata == LUA_NULL_USERDATA)
+ {
+ return luaL_error(L, "attemp to index %s on a nil value", lua_tostring(L, 2));
+ }
+
+ if (useEnv)
+ {
+ lua_getfenv(L, 1); // stack: t, k, v, _env
+ lua_insert(L, -3);
+ lua_settable(L, -3);
+ lua_pop(L, 1);
+ return 0;
+ }
+ }
+ else if (t == LUA_TTABLE)
+ {
+ lua_getmetatable(L, 1); // stack: t k v mt
+
+ while (lua_istable(L, -1)) // stack: t k v mt
+ {
+ lua_pushlightuserdata(L, &settag); // stack: t k v mt tset
+ lua_rawget(L, -2);
+
+ if (lua_istable(L,-1))
+ {
+ lua_pushvalue(L,2); // stack: t k v mt tset k
+ lua_rawget(L,-2);
+
+ if (lua_isfunction(L,-1))
+ {
+ lua_pushvalue(L,1);
+ lua_pushvalue(L,3);
+ lua_call(L,2,0);
+ return 0;
+ }
+
+ lua_pop(L, 1); // stack: t k v mt tset
+ }
+
+ lua_pop(L, 1); // stack: t k v mt
+
+ if (lua_getmetatable(L, -1) == 0) // stack: t k v mt mt
+ {
+ lua_pushnil(L);
+ }
+
+ lua_remove(L, -2); // stack: t k v mt
+ }
+ }
+
+ lua_settop(L, 3);
+ return luaL_error(L, "field or property %s does not exist", lua_tostring(L, 2));
+}
+
+static int enum_index_event (lua_State *L)
+{
+ lua_getmetatable(L, 1); //stack: t, k, mt
+
+ if (lua_istable(L, -1))
+ {
+ lua_pushvalue(L, 2); //stack: t, k, mt, k
+ lua_rawget(L, -2); //stack: t, k, mt, v
+
+ if (!lua_isnil(L, -1))
+ {
+ return 1;
+ }
+
+ lua_pop(L, 1); //stack: t, k, mt
+ lua_pushlightuserdata(L, &gettag);
+ lua_rawget(L, -2); //stack: t, k, mt, tget
+
+ if (lua_istable(L,-1))
+ {
+ lua_pushvalue(L,2); //stack: t k mt tget k
+ lua_rawget(L,-2); //stack: t k mt tget v
+
+ if (lua_isfunction(L,-1))
+ {
+ lua_call(L, 0, 1);
+ lua_pushvalue(L,2);
+ lua_pushvalue(L,-2);
+ lua_rawset(L, 3);
+ return 1;
+ }
+
+ lua_pop(L, 1);
+ }
+ }
+
+ lua_settop(L, 2);
+ lua_pushnil(L);
+ return 1;
+}
+
+static int enum_newindex_event(lua_State *L)
+{
+ luaL_error(L, "the left-hand side of an assignment must be a variable, a property or an indexer");
+ return 1;
+}
+
+static int static_index_event(lua_State *L)
+{
+ lua_pushvalue(L, 2); //stack: t key key
+ lua_rawget(L, 1); //stack: t key value
+
+ if (!lua_isnil(L, -1))
+ {
+ return 1;
+ }
+
+ lua_pop(L, 1);
+ lua_pushlightuserdata(L, &gettag); //stack: t key tag
+ lua_rawget(L, 1); //stack: t key tget
+
+ if (lua_istable(L, -1))
+ {
+ lua_pushvalue(L, 2); //stack: obj key tget key
+ lua_rawget(L, -2); //stack: obj key tget func
+
+ if (lua_isfunction(L, -1))
+ {
+ lua_call(L, 0, 1);
+ return 1;
+ }
+ }
+
+ lua_settop(L, 2);
+
+ if (_preload(L))
+ {
+ return 1;
+ }
+
+ if (toluaflags & FLAG_INDEX_ERROR)
+ {
+ luaL_error(L, "field or property %s does not exist", lua_tostring(L, 2));
+ }
+
+ return 1;
+}
+
+static int static_newindex_event(lua_State *L)
+{
+ lua_pushlightuserdata(L, &settag); //stack: t k v tag
+ lua_rawget(L, 1); //stack: t k v tset
+
+ if (lua_istable(L,-1))
+ {
+ lua_pushvalue(L, 2); //stack: t k v tset k
+ lua_rawget(L, -2); //stack: t k v tset func
+
+ if (lua_isfunction(L, -1))
+ {
+ lua_pushvalue(L,1);
+ lua_pushvalue(L,3);
+ lua_call(L,2,0);
+ return 0;
+ }
+ }
+
+ lua_settop(L, 3);
+ luaL_error(L, "field or property %s does not exist", lua_tostring(L, 2));
+ return 1;
+}
+
+static int vptr_index_event(lua_State *L)
+{
+ lua_pushlightuserdata(L, &vptr);
+ lua_rawget(L, 1); // stack: t key u
+ lua_replace(L, 1); // stack: u key
+ lua_pushvalue(L, 1); // stack: u key u
+
+ while (lua_getmetatable(L, -1) != 0)
+ {
+ lua_remove(L, -2); // stack: u key mt
+ lua_pushvalue(L, 2); // stack: u key mt key
+ lua_rawget(L, -2); // stack: u key mt value
+
+ if (!lua_isnil(L, -1))
+ {
+ return 1;
+ }
+
+ lua_pop(L, 1);
+ lua_pushlightuserdata(L, &gettag);
+ lua_rawget(L, -2); //stack: u key mt tget
+
+ if (lua_istable(L, -1))
+ {
+ lua_pushvalue(L, 2); //stack: obj key mt tget key
+ lua_rawget(L, -2); //stack: obj key mt tget value
+
+ if (lua_isfunction(L, -1))
+ {
+ lua_pushvalue(L, 1);
+ lua_call(L, 1, 1);
+ return 1;
+ }
+ }
+
+ lua_settop(L, 3);
+ }
+
+ lua_settop(L, 2);
+ lua_pushnil(L);
+ return 1;
+}
+
+static int vptr_newindex_event(lua_State *L)
+{
+ lua_pushlightuserdata(L, &vptr);
+ lua_rawget(L, 1); // stack: t key v u
+ lua_getmetatable(L, -1);
+
+ while (lua_istable(L, -1)) // stack: u k v mt
+ {
+ lua_pushlightuserdata(L, &settag);
+ lua_rawget(L, -2); // stack: u k v mt tset
+
+ if (lua_istable(L, -1))
+ {
+ lua_pushvalue(L, 2);
+ lua_rawget(L, -2); // stack: u k v mt tset func
+
+ if (lua_isfunction(L, -1))
+ {
+ lua_pushvalue(L, 4);
+ lua_pushvalue(L, 3);
+ lua_call(L, 2, 0);
+ return 0;
+ }
+
+ lua_pop(L, 1); // stack: t k v mt tset
+ }
+
+ lua_pop(L, 1); // stack: t k v mt
+
+ if (lua_getmetatable(L, -1) == 0) // stack: t k v mt mt
+ {
+ lua_pushnil(L);
+ }
+
+ lua_remove(L, -2); // stack: t k v mt
+ }
+
+ lua_settop(L, 3);
+ return 1;
+}
+
+LUALIB_API bool tolua_isvptrtable(lua_State *L, int index)
+{
+ lua_pushlightuserdata(L, &vptr);
+ lua_rawget(L, index);
+ bool flag = lua_isnil(L, -1) ? false : true;
+ lua_pop(L, 1);
+ return flag;
+}
+
+LUALIB_API void tolua_setindex(lua_State *L)
+{
+ lua_pushstring(L, "__index");
+ lua_pushcfunction(L, class_index_event);
+ lua_rawset(L, -3);
+}
+
+LUALIB_API void tolua_setnewindex(lua_State *L)
+{
+ lua_pushstring(L, "__newindex");
+ lua_pushcfunction(L, class_newindex_event);
+ lua_rawset(L, -3);
+}
+
+LUALIB_API bool tolua_pushudata(lua_State *L, int index)
+{
+ lua_getref(L, LUA_RIDX_UBOX); // stack: ubox
+ lua_rawgeti(L, -1, index); // stack: ubox, obj
+
+ if (!lua_isnil(L, -1))
+ {
+ lua_remove(L, -2); // stack: obj
+ return true;
+ }
+
+ lua_pop(L, 2);
+ return false;
+}
+
+LUALIB_API void tolua_pushnewudata(lua_State *L, int metaRef, int index)
+{
+ lua_getref(L, LUA_RIDX_UBOX);
+ tolua_newudata(L, index);
+ lua_getref(L, metaRef);
+ lua_setmetatable(L, -2);
+ lua_pushvalue(L, -1);
+ lua_rawseti(L, -3, index);
+ lua_remove(L, -2);
+}
+
+static int module_index_event(lua_State *L)
+{
+ lua_pushvalue(L, 2); //stack: t key key
+ lua_rawget(L, 1); //stack: t key value
+
+ if (!lua_isnil(L, -1))
+ {
+ return 1;
+ }
+
+ lua_pop(L, 1); //stack: t key
+ lua_pushstring(L, ".name"); //stack: t key ".name"
+ lua_rawget(L, 1);
+
+ if (!lua_isnil(L, -1)) //stack: t key space
+ {
+ lua_getref(L, LUA_RIDX_PRELOAD); //stack: t key space preload
+ lua_pushvalue(L, -2);
+ lua_pushstring(L, ".");
+ lua_pushvalue(L, 2);
+ lua_concat(L, 3); //stack: t key space preload key
+ lua_pushvalue(L, -1); //stack: t key space preload key1 key1
+ lua_rawget(L, -3); //stack: t key space preload key1 value
+
+ if (!lua_isnil(L, -1))
+ {
+ lua_pop(L, 1); //stack: t key space preload key1
+ lua_getref(L, LUA_RIDX_REQUIRE);
+ lua_pushvalue(L, -2);
+ lua_call(L, 1, 1);
+ }
+ else
+ {
+ lua_pushnil(L);
+ }
+ }
+
+ return 1;
+}
+
+typedef struct stringbuffer
+{
+ const char *buffer;
+ size_t len;
+} stringbuffer;
+
+static stringbuffer sb;
+
+void initmodulebuffer()
+{
+ sb.len = 0;
+ sb.buffer = NULL;
+}
+
+void pushmodule(lua_State *L, const char *str)
+{
+ luaL_Buffer b;
+ luaL_buffinit(L, &b);
+
+ if (sb.len > 0)
+ {
+ luaL_addlstring(&b, sb.buffer, sb.len);
+ luaL_addchar(&b, '.');
+ }
+
+ luaL_addstring(&b, str);
+ luaL_pushresult(&b);
+ sb.buffer = lua_tolstring(L, -1, &sb.len);
+}
+
+LUALIB_API bool tolua_beginmodule(lua_State *L, const char *name)
+{
+ if (name != NULL)
+ {
+ lua_pushstring(L, name); //stack key
+ lua_rawget(L, -2); //stack value
+
+ if (lua_isnil(L, -1))
+ {
+ lua_pop(L, 1);
+ lua_newtable(L); //stack table
+
+ lua_pushstring(L, "__index");
+ lua_pushcfunction(L, module_index_event);
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, name); //stack table name
+ lua_pushstring(L, ".name"); //stack table name ".name"
+ pushmodule(L, name); //stack table name ".name" module
+ lua_rawset(L, -4); //stack table name
+ lua_pushvalue(L, -2); //stack table name table
+ lua_rawset(L, -4); //stack table
+
+ lua_pushvalue(L, -1);
+ lua_setmetatable(L, -2);
+ return true;
+ }
+ else if (lua_istable(L, -1))
+ {
+ if (lua_getmetatable(L, -1) == 0)
+ {
+ lua_pushstring(L, "__index");
+ lua_pushcfunction(L, module_index_event);
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, name); //stack table name
+ lua_pushstring(L, ".name"); //stack table name ".name"
+ pushmodule(L, name); //stack table name ".name" module
+ lua_rawset(L, -4); //stack table name
+ lua_pushvalue(L, -2); //stack table name table
+ lua_rawset(L, -4); //stack table
+
+ lua_pushvalue(L, -1);
+ lua_setmetatable(L, -2);
+ }
+ else
+ {
+ lua_pushstring(L, ".name");
+ lua_gettable(L, -3);
+ sb.buffer = lua_tolstring(L, -1, &sb.len);
+ lua_pop(L, 2);
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+ else
+ {
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
+ return true;
+ }
+}
+
+LUALIB_API void tolua_endmodule(lua_State *L)
+{
+ lua_pop(L, 1);
+ int len = (int)sb.len;
+
+ while(len-- >= 0)
+ {
+ if (sb.buffer[len] == '.')
+ {
+ sb.len = len;
+ return;
+ }
+ }
+
+ sb.len = 0;
+}
+
+static int class_new_event(lua_State *L)
+{
+ if (!lua_istable(L, 1))
+ {
+ return luaL_typerror(L, 1, "table");
+ }
+
+ int count = lua_gettop(L);
+ lua_pushvalue(L,1);
+
+ if (lua_getmetatable(L,-1))
+ {
+ lua_remove(L,-2);
+ lua_pushstring(L, "New");
+ lua_rawget(L,-2);
+
+ if (lua_isfunction(L,-1))
+ {
+ for (int i = 2; i <= count; i++)
+ {
+ lua_pushvalue(L, i);
+ }
+
+ lua_call(L, count - 1, 1);
+ return 1;
+ }
+
+ lua_settop(L,3);
+ }
+
+ return luaL_error(L,"attempt to perform ctor operation failed");
+}
+
+static void _pushfullname(lua_State *L, int pos)
+{
+ if (sb.len > 0)
+ {
+ lua_pushlstring(L, sb.buffer, sb.len);
+ lua_pushstring(L, ".");
+ lua_pushvalue(L, pos < 0 ? pos - 2 : pos + 2);
+ lua_concat(L, 3);
+ }
+ else
+ {
+ lua_pushvalue(L, pos);
+ }
+}
+
+static void _addtoloaded(lua_State *L)
+{
+ lua_getref(L, LUA_RIDX_LOADED);
+ _pushfullname(L, -3);
+ lua_pushvalue(L, -3);
+ lua_rawset(L, -3);
+ lua_pop(L, 1);
+}
+
+LUALIB_API int tolua_beginclass(lua_State *L, const char *name, int baseType, int ref)
+{
+ int reference = ref;
+ lua_pushstring(L, name);
+ lua_newtable(L);
+ _addtoloaded(L);
+
+ if (ref == LUA_REFNIL)
+ {
+ lua_newtable(L);
+ lua_pushvalue(L, -1);
+ reference = luaL_ref(L, LUA_REGISTRYINDEX);
+ }
+ else
+ {
+ lua_getref(L, reference);
+ }
+
+ if (baseType != 0)
+ {
+ lua_getref(L, baseType);
+ lua_setmetatable(L, -2);
+ }
+
+ lua_pushlightuserdata(L, &tag);
+ lua_pushnumber(L, 1);
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, ".name");
+ _pushfullname(L, -4);
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, ".ref");
+ lua_pushinteger(L, reference);
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, "__call");
+ lua_pushcfunction(L, class_new_event);
+ lua_rawset(L, -3);
+
+ tolua_setindex(L);
+ tolua_setnewindex(L);
+ return reference;
+}
+
+
+LUALIB_API void tolua_endclass(lua_State *L)
+{
+ lua_setmetatable(L, -2);
+ lua_rawset(L, -3);
+}
+
+/*void settablename(lua_State *L, const char *label, const char *name)
+{
+ lua_pushstring(L, "name");
+ char cname[128];
+ int l1 = strlen(label);
+ int l2 = strlen(name) ;
+ strncat(cname, label, 128 - l1);
+ strncat(cname, name, 128 - l1 - l2);
+ lua_pushstring(L, cname);
+ lua_rawset(L, -3);
+}*/
+
+LUALIB_API int tolua_beginenum(lua_State *L, const char *name)
+{
+ lua_pushstring(L, name);
+ lua_newtable(L);
+ _addtoloaded(L);
+ lua_newtable(L);
+ lua_pushvalue(L, -1);
+ int reference = luaL_ref(L, LUA_REGISTRYINDEX);
+ lua_pushlightuserdata(L, &tag);
+ lua_pushnumber(L, 1);
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, ".name");
+ _pushfullname(L, -4);
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, "__index");
+ lua_pushcfunction(L, enum_index_event);
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, "__newindex");
+ lua_pushcfunction(L, enum_newindex_event);
+ lua_rawset(L, -3);
+
+ return reference;
+}
+
+LUALIB_API void tolua_endenum(lua_State *L)
+{
+ lua_setmetatable(L, -2);
+ lua_rawset(L, -3);
+}
+
+LUALIB_API void tolua_beginstaticclass(lua_State *L, const char *name)
+{
+ lua_pushstring(L, name);
+ lua_newtable(L);
+ _addtoloaded(L);
+ lua_pushvalue(L, -1);
+
+ lua_pushlightuserdata(L, &tag);
+ lua_pushnumber(L, 1);
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, ".name");
+ _pushfullname(L, -4);
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, "__index");
+ lua_pushcfunction(L, static_index_event);
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, "__newindex");
+ lua_pushcfunction(L, static_newindex_event);
+ lua_rawset(L, -3);
+}
+
+LUALIB_API void tolua_endstaticclass(lua_State *L)
+{
+ lua_setmetatable(L, -2);
+ lua_rawset(L, -3);
+}
+
+LUALIB_API void tolua_constant(lua_State *L, const char *name, double value)
+{
+ lua_pushstring(L, name);
+ lua_pushnumber(L, value);
+ lua_rawset(L,-3);
+}
+
+LUALIB_API void tolua_function(lua_State *L, const char *name, lua_CFunction fn)
+{
+ lua_pushstring(L, name);
+ tolua_pushcfunction(L, fn);
+ lua_rawset(L, -3);
+
+ /*lua_pushstring(L, name);
+ lua_pushcfunction(L, fn);
+ lua_rawset(L, -3);*/
+}
+
+LUALIB_API void tolua_variable(lua_State *L, const char *name, lua_CFunction get, lua_CFunction set)
+{
+ lua_pushlightuserdata(L, &gettag);
+ lua_rawget(L, -2);
+
+ if (!lua_istable(L, -1))
+ {
+ /* create .get table, leaving it at the top */
+ lua_pop(L, 1);
+ lua_newtable(L);
+ lua_pushlightuserdata(L, &gettag);
+ lua_pushvalue(L, -2);
+ lua_rawset(L, -4);
+ }
+
+ lua_pushstring(L, name);
+ //lua_pushcfunction(L, get);
+ tolua_pushcfunction(L, get);
+ lua_rawset(L, -3); /* store variable */
+ lua_pop(L, 1); /* pop .get table */
+
+ /* set func */
+ if (set != NULL)
+ {
+ lua_pushlightuserdata(L, &settag);
+ lua_rawget(L, -2);
+
+ if (!lua_istable(L, -1))
+ {
+ /* create .set table, leaving it at the top */
+ lua_pop(L, 1);
+ lua_newtable(L);
+ lua_pushlightuserdata(L, &settag);
+ lua_pushvalue(L, -2);
+ lua_rawset(L, -4);
+ }
+
+ lua_pushstring(L, name);
+ //lua_pushcfunction(L, set);
+ tolua_pushcfunction(L, set);
+ lua_rawset(L, -3); /* store variable */
+ lua_pop(L, 1); /* pop .set table */
+ }
+}
+
+LUALIB_API int toluaL_ref(lua_State *L)
+{
+ int stackPos = abs_index(L, -1);
+ lua_getref(L, LUA_RIDX_FIXEDMAP);
+ lua_pushvalue(L, stackPos);
+ lua_rawget(L, -2);
+
+ if (!lua_isnil(L, -1))
+ {
+ int ref = (int)lua_tointeger(L, -1);
+ lua_pop(L, 3);
+ return ref;
+ }
+ else
+ {
+ lua_pushvalue(L, stackPos);
+ int ref = luaL_ref(L, LUA_REGISTRYINDEX);
+ lua_pushvalue(L, stackPos);
+ lua_pushinteger(L, ref);
+ lua_rawset(L, -4);
+ lua_pop(L, 3);
+ return ref;
+ }
+}
+
+LUALIB_API void toluaL_unref(lua_State *L, int reference)
+{
+ lua_getref(L, LUA_RIDX_FIXEDMAP);
+ lua_getref(L, reference);
+ lua_pushnil(L);
+ lua_rawset(L, -3);
+ luaL_unref(L, LUA_REGISTRYINDEX, reference);
+ lua_pop(L, 1);
+}
+
+LUA_API lua_State* tolua_getmainstate(lua_State *L1)
+{
+ lua_rawgeti(L1, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD);
+ lua_State *L = lua_tothread(L1, -1);
+ lua_pop(L1, 1);
+ return L;
+}
+
+LUA_API int tolua_getvaluetype(lua_State *L, int stackPos)
+{
+ stackPos = abs_index(L, stackPos);
+ lua_getref(L, LUA_RIDX_CHECKVALUE);
+ lua_pushvalue(L, stackPos);
+ lua_call(L, 1, 1);
+ int ret = (int)lua_tonumber(L, -1);
+ lua_pop(L, 1);
+ return ret;
+}
+
+LUALIB_API bool tolua_createtable(lua_State *L, const char *path, int szhint)
+{
+ const char *e = NULL;
+ lua_pushvalue(L, LUA_GLOBALSINDEX); //stack _G
+
+ do
+ {
+ e = strchr(path, '.');
+ if (e == NULL) e = path + strlen(path);
+ lua_pushlstring(L, path, e - path); //stack _G key
+ lua_rawget(L, -2); //stack _G value
+ int type = lua_type(L, -1);
+
+ if (type == LUA_TNIL)
+ {
+ lua_pop(L, 1); //stack _G
+ lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); //stack _G table
+ lua_pushlstring(L, path, e - path); //stack _G table name
+ lua_pushvalue(L, -2); //stack _G table name table
+ lua_settable(L, -4); //stack _G table
+ }
+ else if (type != LUA_TTABLE)
+ {
+ lua_pop(L, 2);
+ return false;
+ }
+
+ lua_remove(L, -2); //stack table
+ path = e + 1;
+ } while (*e == '.');
+
+ return true;
+}
+
+LUALIB_API bool tolua_beginpremodule(lua_State *L, const char *path, int szhint)
+{
+ const char *e = NULL;
+ const char *name = path;
+ lua_pushvalue(L, LUA_GLOBALSINDEX); //stack _G
+
+ do
+ {
+ e = strchr(path, '.');
+ if (e == NULL) e = path + strlen(path);
+ lua_pushlstring(L, path, e - path); //stack t key
+ lua_rawget(L, -2); //stack t value
+ int type = lua_type(L, -1);
+
+ if (type == LUA_TNIL)
+ {
+ lua_pop(L, 1); //stack t
+ lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); //stack t table
+ lua_pushlstring(L, path, e - path); //stack t table name
+ lua_pushvalue(L, -2); //stack t table name table
+ lua_settable(L, -4); //stack t table
+
+ lua_pushstring(L, ".name");
+ pushmodule(L, name);
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, "__index");
+ lua_pushcfunction(L, module_index_event);
+ lua_rawset(L, -3);
+ }
+ else if (type != LUA_TTABLE)
+ {
+ lua_pop(L, 1);
+ return false;
+ }
+
+ lua_remove(L, -2); //stack table
+ path = e + 1;
+ } while (*e == '.');
+
+ lua_pushstring(L, ".name");
+ lua_gettable(L, -2);
+ sb.buffer = lua_tolstring(L, -1, &sb.len);
+ lua_pop(L, 1);
+ return true;
+}
+
+LUALIB_API bool tolua_endpremodule(lua_State *L, int ref)
+{
+ lua_getref(L, ref);
+ lua_pushstring(L, ".name");
+ lua_rawget(L, -2);
+
+ if (!tolua_createtable(L, lua_tostring(L, -1), 0))
+ {
+ lua_pushnil(L);
+ }
+
+ sb.len = 0;
+ return true;
+}
+
+LUALIB_API bool tolua_addpreload(lua_State *L, const char *path)
+{
+ const char *e = NULL;
+ const char *name = path;
+ int top = lua_gettop(L);
+ lua_pushvalue(L, LUA_GLOBALSINDEX); //stack _G
+
+ do
+ {
+ e = strchr(path, '.');
+ if (e == NULL) e = path + strlen(path);
+ lua_pushlstring(L, path, e - path); //stack t key
+ lua_rawget(L, -2); //stack t value
+ int type = lua_type(L, -1);
+
+ if (type == LUA_TNIL)
+ {
+ lua_pop(L, 1); //stack t
+ lua_createtable(L, 0, 0); //stack t table
+ lua_pushlstring(L, path, e - path); //stack t table name
+ lua_pushvalue(L, -2); //stack t table name table
+ lua_settable(L, -4); //stack t table
+
+ lua_pushstring(L, ".name");
+ lua_pushstring(L, name);
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, "__index");
+ lua_pushcfunction(L, module_index_event);
+ lua_rawset(L, -3);
+ }
+ else if (type != LUA_TTABLE)
+ {
+ lua_settop(L, top);
+ return false;
+ }
+
+ lua_remove(L, -2); //stack table
+ path = e + 1;
+ } while (*e == '.');
+
+ lua_settop(L, top);
+ return true;
+}
+
+LUALIB_API int tolua_getclassref(lua_State *L, int pos)
+{
+ lua_getmetatable(L, pos); //mt
+ lua_pushstring(L, ".ref"); //mt .ref
+ lua_rawget(L, -2); //mt ref
+ int ref = (int)lua_tointeger(L, -1);
+ return ref;
+}
+
+LUALIB_API bool tolua_pushluatable(lua_State *L, const char *path)
+{
+ const char *e = NULL;
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
+
+ do
+ {
+ e = strchr(path, '.');
+ if (e == NULL) e = path + strlen(path);
+ lua_pushlstring(L, path, e - path);
+ lua_rawget(L, -2);
+
+ if (!lua_istable(L, -1))
+ {
+ lua_pop(L, 2);
+ return false;
+ }
+
+ lua_remove(L, -2);
+ path = e + 1;
+ } while (*e == '.');
+
+ return true;
+}
+
+LUALIB_API const char* tolua_typename(lua_State *L, int lo)
+{
+ int tag = lua_type(L,lo);
+
+ if (tag == LUA_TNONE)
+ {
+ lua_pushstring(L,"[no object]");
+ }
+ else if (tag != LUA_TUSERDATA && tag != LUA_TTABLE)
+ {
+ lua_pushstring(L, lua_typename(L,tag));
+ }
+ else if (tag == LUA_TUSERDATA)
+ {
+ if (!lua_getmetatable(L,lo))
+ {
+ lua_pushstring(L, lua_typename(L,tag));
+ }
+ else
+ {
+ lua_pushstring(L, ".name");
+ lua_rawget(L, -2);
+
+ if (!lua_isstring(L,-1))
+ {
+ lua_pop(L,1);
+ lua_pushstring(L,"[undefined]");
+ }
+ }
+ }
+ else //is table
+ {
+ lua_pushvalue(L,lo);
+
+ if (!lua_getmetatable(L,lo))
+ {
+ lua_pop(L,1);
+ lua_pushstring(L,"table");
+ }
+ else
+ {
+ lua_pushstring(L, ".name");
+ lua_rawget(L, -2);
+
+ lua_pushstring(L,"class ");
+ lua_insert(L,-2);
+ lua_concat(L,2);
+ }
+ }
+
+ return lua_tostring(L, -1);
+}
+
+LUALIB_API int tolua_getmetatableref(lua_State *L, int pos)
+{
+ int ref = LUA_REFNIL;
+
+ if (lua_getmetatable(L, pos) != 0)
+ {
+ lua_pushstring(L, ".ref");
+ lua_rawget(L, -2);
+
+ if (lua_isnumber(L, -1))
+ {
+ ref = (int)lua_tointeger(L, -1);
+ }
+
+ lua_pop(L, 2);
+ }
+
+ return ref;
+}
+
+static lua_State* getthread(lua_State *L, int *arg)
+{
+ if (lua_isthread(L, 1))
+ {
+ *arg = 1;
+ return lua_tothread(L, 1);
+ }
+ else
+ {
+ *arg = 0;
+ return L;
+ }
+}
+
+static int traceback(lua_State *L)
+{
+ int arg;
+ lua_State *L1 = getthread(L, &arg);
+ const char *msg = lua_tostring(L, arg + 1);
+
+ if (msg == NULL && !lua_isnoneornil(L, arg + 1))
+ {
+ lua_pushvalue(L, arg + 1);
+ }
+ else
+ {
+ if (NULL != strstr(msg, "stack traceback:"))
+ {
+ lua_pushvalue(L, arg + 1);
+ return 1;
+ }
+
+ int level = (int)luaL_optinteger(L, arg + 2, (L == L1) ? 1 : 0);
+#ifdef LUAJIT_VERSION
+ luaL_traceback(L, L1, msg, level);
+#else
+ lua_getref(L, LUA_RIDX_TRACEBACK);
+ lua_pushthread(L1);
+ lua_pushvalue(L, arg + 1);
+ lua_pushnumber(L, level + 1);
+ lua_call(L, 3, 1);
+#endif
+ }
+
+ return 1;
+}
+
+LUALIB_API int tolua_beginpcall(lua_State *L, int reference)
+{
+ lua_getref(L, LUA_RIDX_CUSTOMTRACEBACK);
+ int top = lua_gettop(L);
+ lua_getref(L, reference);
+ return top;
+}
+
+LUALIB_API void tolua_pushtraceback(lua_State *L)
+{
+ lua_getref(L, LUA_RIDX_CUSTOMTRACEBACK);
+}
+
+/*static const int sentinel_ = 0;
+#define sentinel ((void *)&sentinel_)
+
+static int _require(lua_State *L)
+{
+ const char *name = luaL_checkstring(L, 1);
+ lua_settop(L, 1);
+ const char *key = luaL_gsub(L, name, "/", ".");
+ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
+ lua_getfield(L, 3, key);
+
+ if (lua_toboolean(L, -1))
+ {
+ if (lua_touserdata(L, -1) == sentinel)
+ {
+ luaL_error(L, "loop or previous error loading module " LUA_QS, name);
+ }
+
+ return 1; //package is already loaded
+ }
+
+ // else must load it; iterate over available loaders
+ lua_getfield(L, LUA_ENVIRONINDEX, "loaders");
+
+ if (!lua_istable(L, -1))
+ {
+ luaL_error(L, LUA_QL("package.loaders") " must be a table");
+ }
+
+ lua_pushliteral(L, ""); //error message accumulator
+
+ for(int i = 1; ; i++)
+ {
+ lua_rawgeti(L, -2, i); // get a loader
+
+ if (lua_isnil(L, -1))
+ {
+ luaL_error(L, "module " LUA_QS " not found:%s", name, lua_tostring(L, -2));
+ }
+
+ lua_pushstring(L, name);
+ lua_call(L, 1, 1);
+
+ if (lua_isfunction(L, -1)) // did it find module?
+ {
+ break; // module loaded successfully
+ }
+ else if (lua_isstring(L, -1)) // loader returned error message?
+ {
+ lua_concat(L, 2); // accumulate it
+ }
+ else
+ {
+ lua_pop(L, 1);
+ }
+ }
+
+ lua_pushlightuserdata(L, sentinel);
+ lua_setfield(L, 3, key); // _LOADED[name] = sentinel
+ lua_pushstring(L, name); // pass name as argument to module
+ lua_call(L, 1, 1); // run loaded module
+
+ if (!lua_isnil(L, -1)) // non-nil return?
+ {
+ lua_setfield(L, 3, key); // _LOADED[name] = returned value
+ }
+
+ lua_getfield(L, 3, key);
+
+ if (lua_touserdata(L, -1) == sentinel)
+ { // module did not set a value?
+ lua_pushboolean(L, 1); // use true as result
+ lua_pushvalue(L, -1); // extra copy to be returned
+ lua_setfield(L, 3, key); // _LOADED[name] = true
+ }
+
+ return 1;
+}
+
+void tolua_openrequire(lua_State *L)
+{
+ lua_getglobal(L, "require");
+ lua_pushcfunction(L, _require);
+ lua_getfenv(L, -2);
+ lua_setfenv(L, -2);
+ lua_setglobal(L, "require");
+ lua_pop(L, 1);
+}*/
+
+LUALIB_API int tolua_require(lua_State *L, const char *fileName)
+{
+ int top = lua_gettop(L);
+ lua_getref(L, LUA_RIDX_CUSTOMTRACEBACK);
+ lua_getref(L, LUA_RIDX_REQUIRE);
+ lua_pushstring(L, fileName);
+ int ret = lua_pcall(L, 1, -1, top + 1);
+ lua_remove(L, top + 1);
+ return ret;
+}
+
+
+/*LUALIB_API bool tolua_checkluaslot(lua_State *L, int stackPos, int *func, int *table)
+{
+ lua_pushstring(L, "__call");
+ lua_rawget(L, stackPos);
+
+ if (lua_isfunction(L, -1))
+ {
+ *func = toluaL_ref(L);
+ }
+ else
+ {
+ lua_pop(L, 1);
+ return false;
+ }
+
+ lua_pushvalue(L, stackPos);
+ *table = toluaL_ref(L);
+ return true;
+}*/
+
+/*static int do_operator (lua_State *L, const char *op)
+{
+ if (lua_isuserdata(L,1))
+ {
+ lua_pushvalue(L,1);
+
+ while (lua_getmetatable(L,-1))
+ {
+ lua_remove(L,-2);
+ lua_pushstring(L,op);
+ lua_rawget(L,-2);
+
+ if (lua_isfunction(L,-1))
+ {
+ lua_pushvalue(L,1);
+ lua_pushvalue(L,2);
+ lua_call(L,2,1);
+ return 1;
+ }
+
+ lua_settop(L,3);
+ }
+ }
+
+ luaL_error(L,"attempt to perform operation %s failed", op);
+ return 0;
+}
+
+static int class_add_event (lua_State *L)
+{
+ return do_operator(L,"op_Addition");
+}
+
+static int class_sub_event (lua_State *L)
+{
+ return do_operator(L,"op_Subtraction");
+}
+
+static int class_mul_event (lua_State *L)
+{
+ return do_operator(L,"op_Multiply");
+}
+
+static int class_div_event (lua_State *L)
+{
+ return do_operator(L,"op_Division");
+}
+
+static int class_equals_event (lua_State *L)
+{
+ return do_operator(L,"op_Equality");
+}*/
+
+
+#ifdef _WIN32
+double tolua_timegettime()
+{
+ FILETIME ft;
+ double t;
+ GetSystemTimeAsFileTime(&ft);
+ /* Windows file time (time since January 1, 1601 (UTC)) */
+ t = ft.dwLowDateTime / 1.0e7 + ft.dwHighDateTime*(4294967296.0 / 1.0e7);
+ /* convert to Unix Epoch time (time since January 1, 1970 (UTC)) */
+ return (t - 11644473600.0);
+}
+#else
+double tolua_timegettime()
+{
+ struct timeval v;
+ gettimeofday(&v, (struct timezone *) NULL);
+ /* Unix Epoch time (time since January 1, 1970 (UTC)) */
+ return v.tv_sec + v.tv_usec / 1.0e6;
+}
+#endif
+
+static int tolua_gettime(lua_State *L)
+{
+ lua_pushnumber(L, tolua_timegettime());
+ return 1;
+}
+
+static int tolua_bnd_setpeer(lua_State *L)
+{
+ // stack: userdata, table
+ if (!lua_isuserdata(L, -2))
+ {
+ return luaL_error(L, "Invalid argument #1 to setpeer: userdata expected.");
+ }
+
+ if (lua_isnil(L, 2))
+ {
+ lua_pop(L, 1);
+ lua_pushvalue(L, TOLUA_NOPEER);
+ lua_setfenv(L, -2);
+ }
+ else
+ {
+ lua_pushvalue(L, 2); //stack: u p p
+ lua_setfenv(L, -3); //stack: u p
+ lua_newtable(L); //stack: u p vt
+
+ lua_pushlightuserdata(L, &vptr);
+ lua_pushvalue(L, 1);
+ lua_rawset(L, -3);
+ //lua_pushvalue(L, 1);
+ //lua_rawseti(L, -2, 1);
+
+ lua_getref(L, LUA_RIDX_VPTR); //stack: u p vt mt
+ lua_setmetatable(L, -2); //stack: u p vt
+
+ lua_pushstring(L, "base"); //stack: u p vt "base"
+ lua_pushvalue(L, -2); //stack: u p vt "base" vt
+ lua_rawset(L, 2); //stack: u p vt
+ lua_pop(L, 1);
+ }
+
+ return 0;
+};
+
+static int tolua_bnd_getpeer(lua_State *L)
+{
+ lua_getfenv(L, -1);
+
+ if (lua_rawequal(L, -1, TOLUA_NOPEER))
+ {
+ lua_pop(L, 1);
+ lua_pushnil(L);
+ };
+
+ return 1;
+};
+
+static int tolua_bnd_getfunction(lua_State *L)
+{
+ lua_pushvalue(L, 1); // stack: obj key obj
+
+ while (lua_getmetatable(L, -1) != 0) // stack: obj key mt
+ {
+ lua_remove(L, -2); // stack: obj key mt
+
+ lua_pushvalue(L, 2); // stack: obj key mt key
+ lua_rawget(L, -2); // stack: obj key mt value
+
+ if (!lua_isfunction(L, -1))
+ {
+ return 1;
+ }
+ else
+ {
+ lua_pop(L, 1);
+ }
+
+ lua_pushlightuserdata(L, &gettag);
+ lua_rawget(L, -2); //stack: obj key mt tget
+
+ if (lua_istable(L, -1))
+ {
+ lua_pushvalue(L, 2); //stack: obj key mt tget key
+ lua_rawget(L, -2); //stack: obj key mt tget value
+
+ if (lua_isfunction(L, -1))
+ {
+ return 1;
+ }
+ }
+
+ lua_settop(L, 3); //stack: obj key mt
+ }
+
+ lua_settop(L, 2);
+ lua_pushnil(L);
+ return 1;
+}
+
+static int tolua_bnd_type (lua_State *L)
+{
+ tolua_typename(L,lua_gettop(L));
+ return 1;
+}
+
+static int tolua_initgettable(lua_State *L)
+{
+ if (!lua_istable(L, 1))
+ {
+ return luaL_typerror(L, 1, "table");
+ }
+
+ lua_newtable(L);
+ lua_pushlightuserdata(L, &gettag);
+ lua_pushvalue(L, -2);
+ lua_rawset(L, 1);
+ return 1;
+}
+
+static int tolua_initsettable(lua_State *L)
+{
+ if (!lua_istable(L, 1))
+ {
+ return luaL_typerror(L, 1, "table");
+ }
+
+ lua_newtable(L);
+ lua_pushlightuserdata(L, &settag);
+ lua_pushvalue(L, -2);
+ lua_rawset(L, 1);
+ return 1;
+}
+
+void tolua_openvptr(lua_State *L)
+{
+ lua_newtable(L);
+
+ lua_pushstring(L, "__index");
+ lua_pushcfunction(L, vptr_index_event);
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, "__newindex");
+ lua_pushcfunction(L, vptr_newindex_event);
+ lua_rawset(L, -3);
+
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_VPTR);
+}
+
+static const struct luaL_Reg tolua_funcs[] =
+{
+ { "gettime", tolua_gettime },
+ { "typename", tolua_bnd_type },
+ { "setpeer", tolua_bnd_setpeer},
+ { "getpeer", tolua_bnd_getpeer},
+ { "getfunction", tolua_bnd_getfunction},
+ { "initset", tolua_initsettable},
+ { "initget", tolua_initgettable},
+ { "int64", tolua_newint64},
+ { "uint64", tolua_newuint64},
+ { "traceback", traceback},
+ { NULL, NULL }
+};
+
+void tolua_setluabaseridx(lua_State *L)
+{
+ for (int i = 1; i <= 64; i++)
+ {
+ lua_pushinteger(L, i);
+ lua_rawseti(L, LUA_REGISTRYINDEX, i);
+ }
+
+ //同lua5.1.5之后版本放入mainstate和_G
+ lua_pushthread(L);
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD);
+
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS);
+
+ //cache require函数
+ lua_getglobal(L, "require");
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_REQUIRE);
+}
+
+void tolua_openpreload(lua_State *L)
+{
+ lua_getglobal(L, "package");
+ lua_pushstring(L, "preload");
+ lua_rawget(L, -2);
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_PRELOAD);
+ lua_pushstring(L, "loaded");
+ lua_rawget(L, -2);
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_LOADED);
+ lua_pop(L, 1);
+}
+
+void tolua_opentraceback(lua_State *L)
+{
+ lua_getglobal(L, "debug");
+ lua_pushstring(L, "traceback");
+ lua_rawget(L, -2);
+ lua_pushvalue(L, -1);
+ lua_setfield(L, LUA_GLOBALSINDEX, "traceback");
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_TRACEBACK);
+ lua_pop(L, 1);
+
+ lua_pushcfunction(L, traceback);
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_CUSTOMTRACEBACK);
+}
+
+void tolua_openubox(lua_State *L)
+{
+ lua_newtable(L);
+ lua_newtable(L);
+ lua_pushstring(L, "__mode");
+ lua_pushstring(L, "v");
+ lua_rawset(L, -3);
+ lua_setmetatable(L, -2);
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_UBOX);
+}
+
+void tolua_openfixedmap(lua_State *L)
+{
+ lua_newtable(L);
+ //lua_newtable(L);
+ //lua_pushstring(L, "__mode");
+ //lua_pushstring(L, "k");
+ //lua_rawset(L, -3);
+ //lua_setmetatable(L, -2);
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_FIXEDMAP);
+}
+
+//对于下列读取lua 特定文件需要判空报错
+void tolua_openvaluetype(lua_State *L)
+{
+ lua_getglobal(L, "GetLuaValueType");
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_CHECKVALUE);
+}
+
+void tolua_openluavec3(lua_State *L)
+{
+ lua_getglobal(L, "Vector3");
+
+ if (!lua_istable(L, 1))
+ {
+ luaL_error(L, "Vector3 does not exist or not be loaded");
+ return;
+ }
+
+ lua_pushstring(L, "New");
+ lua_rawget(L, -2);
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_PACKVEC3);
+ lua_pushstring(L, "Get");
+ lua_rawget(L, -2);
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_UNPACKVEC3);
+ lua_pop(L, 1);
+}
+
+void tolua_openluavec2(lua_State *L)
+{
+ lua_getglobal(L, "Vector2");
+
+ if (!lua_istable(L, 1))
+ {
+ luaL_error(L, "Vector2 does not exist or not be loaded");
+ return;
+ }
+
+ lua_pushstring(L, "New");
+ lua_rawget(L, -2);
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_PACKVEC2);
+ lua_pushstring(L, "Get");
+ lua_rawget(L, -2);
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_UNPACKVEC2);
+ lua_pop(L, 1);
+}
+
+void tolua_openluavec4(lua_State *L)
+{
+ lua_getglobal(L, "Vector4");
+
+ if (!lua_istable(L, 1))
+ {
+ luaL_error(L, "Vector4 does not exist or not be loaded");
+ return;
+ }
+
+ lua_pushstring(L, "New");
+ lua_rawget(L, -2);
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_PACKVEC4);
+ lua_pushstring(L, "Get");
+ lua_rawget(L, -2);
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_UNPACKVEC4);
+ lua_pop(L, 1);
+}
+
+void tolua_openluaclr(lua_State *L)
+{
+ lua_getglobal(L, "Color");
+
+ if (!lua_istable(L, 1))
+ {
+ luaL_error(L, "Color does not exist or not be loaded");
+ return;
+ }
+
+ lua_pushstring(L, "New");
+ lua_rawget(L, -2);
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_PACKCLR);
+ lua_pushstring(L, "Get");
+ lua_rawget(L, -2);
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_UNPACKCLR);
+ lua_pop(L, 1);
+}
+
+void tolua_openluaquat(lua_State *L)
+{
+ lua_getglobal(L, "Quaternion");
+
+ if (!lua_istable(L, 1))
+ {
+ luaL_error(L, "Quaternion does not exist or not be loaded");
+ return;
+ }
+
+ lua_pushstring(L, "New");
+ lua_rawget(L, -2);
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_PACKQUAT);
+ lua_pushstring(L, "Get");
+ lua_rawget(L, -2);
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_UNPACKQUAT);
+ lua_pop(L, 1);
+}
+
+void tolua_openlualayermask(lua_State *L)
+{
+ lua_getglobal(L, "LayerMask");
+
+ if (!lua_istable(L, 1))
+ {
+ luaL_error(L, "LayerMask does not exist or not be loaded");
+ return;
+ }
+
+ lua_pushstring(L, "New");
+ lua_rawget(L, -2);
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_PACKLAYERMASK);
+ lua_pushstring(L, "Get");
+ lua_rawget(L, -2);
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_UNPACKLAYERMASK);
+ lua_pop(L, 1);
+}
+
+void tolua_openupdate(lua_State *L)
+{
+ lua_getglobal(L, "Update");
+
+ if (!lua_isfunction(L, 1))
+ {
+ luaL_error(L, "Update function does not exist or not be loaded");
+ return;
+ }
+
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_UPDATE);
+ lua_getglobal(L, "LateUpdate");
+
+ if (!lua_isfunction(L, 1))
+ {
+ luaL_error(L, "LateUpdate function does not exist or not be loaded");
+ return;
+ }
+
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_LATEUPDATE);
+ lua_getglobal(L, "FixedUpdate");
+
+ if (!lua_isfunction(L, 1))
+ {
+ luaL_error(L, "FixedUpdate function does not exist or not be loaded");
+ return;
+ }
+
+ lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_FIXEDUPDATE);
+}
+
+
+static int _openlualibs(lua_State *L)
+{
+ tolua_openvaluetype(L);
+ tolua_openluavec3(L);
+ tolua_openluavec2(L);
+ tolua_openluavec4(L);
+ tolua_openluaclr(L);
+ tolua_openluaquat(L);
+ tolua_openlualayermask(L);
+ tolua_openupdate(L);
+ return 0;
+}
+
+LUALIB_API int tolua_openlualibs(lua_State *L)
+{
+ lua_pushcfunction(L, _openlualibs);
+ return lua_pcall(L, 0, -1, 0);
+}
+
+static int mathf_ispoweroftwo(lua_State *L)
+{
+ lua_Integer mask = luaL_checkinteger(L, 1);
+ bool flag = (mask & (mask-1)) == 0 ? true : false;
+ lua_pushboolean(L, flag);
+ return 1;
+}
+
+lua_Integer NextPowerOfTwo(lua_Integer v)
+{
+ v -= 1;
+ v |= v >> 16;
+ v |= v >> 8;
+ v |= v >> 4;
+ v |= v >> 2;
+ v |= v >> 1;
+ return v + 1;
+}
+
+static int mathf_nextpoweroftwo(lua_State *L)
+{
+ lua_Integer v = luaL_checkinteger(L, 1);
+ v = NextPowerOfTwo(v);
+ lua_pushnumber(L, v);
+ return 1;
+}
+
+static int mathf_closestpoweroftwo(lua_State *L)
+{
+ lua_Integer v = luaL_checkinteger(L, 1);
+ lua_Integer nextPower = NextPowerOfTwo (v);
+ lua_Integer prevPower = nextPower >> 1;
+
+ if (v - prevPower < nextPower - v)
+ {
+ lua_pushnumber(L, prevPower);
+ }
+ else
+ {
+ lua_pushnumber(L, nextPower);
+ }
+
+ return 1;
+}
+
+static int mathf_gammatolinearspace(lua_State *L)
+{
+ lua_Number value = luaL_checknumber(L, 1);
+
+ if (value <= 0.04045f)
+ {
+ value /= 12.92f;
+ }
+ else if (value < 1.0f)
+ {
+ value = pow((value + 0.055f)/1.055f, 2.4f);
+ }
+ else
+ {
+ value = pow(value, 2.4f);
+ }
+
+ lua_pushnumber(L, value);
+ return 1;
+}
+
+static int mathf_lineartogammaspace (lua_State *L)
+{
+ lua_Number value = luaL_checknumber(L, 1);
+
+ if (value <= 0.0f)
+ {
+ value = 0;
+ }
+ else if (value <= 0.0031308f)
+ {
+ value *= 12.92f;
+ }
+ else if (value <= 1.0f)
+ {
+ value = 1.055f * powf(value, 0.41666f) - 0.055f;
+ }
+ else
+ {
+ value = powf(value, 0.41666f);
+ }
+
+ lua_pushnumber(L, value);
+ return 1;
+}
+
+static int mathf_normalize(lua_State *L)
+{
+ float x = (float)lua_tonumber(L, 1);
+ float y = (float)lua_tonumber(L, 2);
+ float z = (float)lua_tonumber(L, 3);
+
+ float len = sqrt(x * x + y * y + z * z);
+
+ if (len == 1)
+ {
+ lua_pushnumber(L, x);
+ lua_pushnumber(L, y);
+ lua_pushnumber(L, z);
+ }
+ else if (len > 1e-5)
+ {
+ lua_pushnumber(L, x);
+ lua_pushnumber(L, y);
+ lua_pushnumber(L, z);
+ }
+ else
+ {
+ lua_pushnumber(L, 0);
+ lua_pushnumber(L, 0);
+ lua_pushnumber(L, 0);
+ }
+
+ return 3;
+}
+
+static const struct luaL_Reg tolua_mathf[] =
+{
+ { "NextPowerOfTwo", mathf_nextpoweroftwo },
+ { "ClosestPowerOfTwo", mathf_closestpoweroftwo },
+ { "IsPowerOfTwo", mathf_ispoweroftwo},
+ { "GammaToLinearSpace", mathf_gammatolinearspace},
+ { "LinearToGammaSpace", mathf_lineartogammaspace},
+ { "Normalize", mathf_normalize},
+ { NULL, NULL }
+};
+
+LUALIB_API void tolua_openlibs(lua_State *L)
+{
+ initmodulebuffer();
+ luaL_openlibs(L);
+ int top = lua_gettop(L);
+
+ tolua_setluabaseridx(L);
+ tolua_opentraceback(L);
+ tolua_openpreload(L);
+ tolua_openubox(L);
+ tolua_openfixedmap(L);
+ tolua_openint64(L);
+ tolua_openuint64(L);
+ tolua_openvptr(L);
+ //tolua_openrequire(L);
+
+ luaL_register(L, "Mathf", tolua_mathf);
+ luaL_register(L, "tolua", tolua_funcs);
+
+ lua_getglobal(L, "tolua");
+
+ lua_pushstring(L, "gettag");
+ lua_pushlightuserdata(L, &gettag);
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, "settag");
+ lua_pushlightuserdata(L, &settag);
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, "version");
+ lua_pushstring(L, "1.0.7");
+ lua_rawset(L, -3);
+
+ lua_settop(L,top);
+}
+
+LUALIB_API void tolua_setflag(int bit, bool flag)
+{
+ if (flag)
+ {
+ toluaflags |= bit;
+ }
+ else
+ {
+ toluaflags &= ~bit;
+ }
+}
+
+LUALIB_API bool tolua_getflag(int bit)
+{
+ return toluaflags & bit ? true : false;
+}
+
+static luaL_Buffer lua_buffer[3];
+static int _bufferIndex = 0;
+
+LUALIB_API luaL_Buffer* tolua_buffinit(lua_State *L)
+{
+ luaL_Buffer* buffer = &lua_buffer[_bufferIndex & 3];
+ luaL_buffinit(L, buffer);
+ ++_bufferIndex;
+ return buffer;
+}
+
+LUALIB_API void tolua_addlstring(luaL_Buffer *b, const char *s, int l)
+{
+ luaL_addlstring(b, s, (size_t)l);
+}
+
+LUALIB_API void tolua_addstring(luaL_Buffer *b, const char *s)
+{
+ luaL_addstring(b, s);
+}
+
+LUALIB_API void tolua_pushresult(luaL_Buffer *b)
+{
+ luaL_pushresult(b);
+}
+
+LUALIB_API void tolua_addchar(luaL_Buffer *b, char c)
+{
+ luaL_addchar(b, c);
+}
+
+LUALIB_API int tolua_update(lua_State *L, float deltaTime, float unscaledTime)
+{
+ int top = tolua_beginpcall(L, LUA_RIDX_UPDATE);
+ lua_pushnumber(L, deltaTime);
+ lua_pushnumber(L, unscaledTime);
+ return lua_pcall(L, 2, -1, top);
+}
+
+LUALIB_API int tolua_lateupdate(lua_State *L)
+{
+ int top = tolua_beginpcall(L, LUA_RIDX_LATEUPDATE);
+ return lua_pcall(L, 0, -1, top);
+}
+
+LUALIB_API int tolua_fixedupdate(lua_State *L, float fixedTime)
+{
+ int top = tolua_beginpcall(L, LUA_RIDX_FIXEDUPDATE);
+ lua_pushnumber(L, fixedTime);
+ return lua_pcall(L, 1, -1, top);
+}
+
+static int index_op_this(lua_State *L)
+{
+ lua_pushvalue(L, 2); //stack: t, k, k
+ lua_rawget(L, -2); //stack: t, k, v
+
+ if (!lua_isnil(L, -1))
+ {
+ lua_pushlightuserdata(L, &vptr); // stack: t, k, v, vptr
+ lua_rawget(L, 1); // stack: t, k, v, u
+ lua_replace(L, 1); // stack: u, k, v
+ }
+
+ return 1;
+}
+
+static int newindex_op_this(lua_State *L)
+{
+ lua_pushvalue(L, 2); //stack: t, k, v, k
+ lua_rawget(L, 1); //stack: t, k, v, f
+
+ if (!lua_isnil(L, -1))
+ {
+ lua_pushlightuserdata(L, &vptr); // stack: t, k, v, f, vptr
+ lua_rawget(L, 1); // stack: t, k, v, f, u
+ lua_replace(L, 1); // stack: u, k, v, f
+ }
+
+ return 1;
+}
+
+LUALIB_API void tolua_regthis(lua_State *L, lua_CFunction get, lua_CFunction set)
+{
+ lua_newtable(L); //u t
+
+ lua_pushlightuserdata(L, &vptr);
+ lua_pushvalue(L, -3);
+ lua_rawset(L, -3);
+
+ if (get != NULL)
+ {
+ lua_pushstring(L, "get");
+ tolua_pushcfunction(L, get);
+ lua_rawset(L, -3);
+ }
+
+ if (set != NULL)
+ {
+ lua_pushstring(L, "set");
+ tolua_pushcfunction(L, set);
+ lua_rawset(L, -3);
+ }
+
+ lua_pushstring(L, "__index");
+ lua_pushcfunction(L, index_op_this);
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, "__newindex");
+ lua_pushcfunction(L, newindex_op_this);
+ lua_rawset(L, -3);
+}
+
+LUALIB_API int tolua_where (lua_State *L, int level)
+{
+ lua_Debug ar;
+
+ if (lua_getstack(L, level, &ar))
+ {
+ lua_getinfo(L, "Sl", &ar);
+
+ if (ar.currentline > 0)
+ {
+ lua_pushstring(L, ar.source);
+ return ar.currentline;
+ }
+ }
+
+ lua_pushliteral(L, "");
+ return -1;
+} \ No newline at end of file