mirror of https://github.com/lua/lua
new API for registry and C upvalues + new implementation for references
This commit is contained in:
parent
7cd37142f4
commit
1e81da51ba
120
lapi.c
120
lapi.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lapi.c,v 1.152 2001/09/07 17:39:10 roberto Exp $
|
||||
** $Id: lapi.c,v 1.154 2001/10/11 21:40:56 roberto Exp $
|
||||
** Lua API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -40,15 +40,28 @@ const l_char lua_ident[] =
|
|||
|
||||
|
||||
|
||||
static TObject *negindex (lua_State *L, int index) {
|
||||
if (index > LUA_REGISTRYINDEX) {
|
||||
api_check(L, index != 0 && -index <= L->top - L->ci->base);
|
||||
return L->top+index;
|
||||
} else if (index == LUA_REGISTRYINDEX) /* pseudo-indices */
|
||||
return &G(L)->registry;
|
||||
else {
|
||||
TObject *func = (L->ci->base - 1);
|
||||
index = LUA_REGISTRYINDEX - index;
|
||||
api_check(L, iscfunction(func) && index <= clvalue(func)->c.nupvalues);
|
||||
return &clvalue(func)->c.upvalue[index-1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TObject *luaA_index (lua_State *L, int index) {
|
||||
if (index > 0) {
|
||||
api_check(L, index <= L->top - L->ci->base);
|
||||
return L->ci->base+index-1;
|
||||
}
|
||||
else {
|
||||
api_check(L, index != 0 && -index <= L->top - L->ci->base);
|
||||
return L->top+index;
|
||||
}
|
||||
else
|
||||
return negindex(L, index);
|
||||
}
|
||||
|
||||
|
||||
|
@ -59,10 +72,8 @@ static TObject *luaA_indexAcceptable (lua_State *L, int index) {
|
|||
if (o >= L->top) return NULL;
|
||||
else return o;
|
||||
}
|
||||
else {
|
||||
api_check(L, index != 0 && -index <= L->top - L->ci->base);
|
||||
return L->top+index;
|
||||
}
|
||||
else
|
||||
return negindex(L, index);
|
||||
}
|
||||
|
||||
|
||||
|
@ -378,24 +389,6 @@ LUA_API void lua_getglobals (lua_State *L) {
|
|||
}
|
||||
|
||||
|
||||
LUA_API int lua_getref (lua_State *L, int ref) {
|
||||
int status;
|
||||
lua_lock(L);
|
||||
if (ref == LUA_REFNIL) {
|
||||
setnilvalue(L->top);
|
||||
status = 1;
|
||||
}
|
||||
else {
|
||||
setobj(L->top, luaH_getnum(G(L)->weakregistry, ref));
|
||||
status = (ttype(L->top) != LUA_TNIL);
|
||||
}
|
||||
if (status)
|
||||
api_incr_top(L);
|
||||
lua_unlock(L);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_newtable (lua_State *L) {
|
||||
lua_lock(L);
|
||||
sethvalue(L->top, luaH_new(L, 0));
|
||||
|
@ -404,22 +397,6 @@ LUA_API void lua_newtable (lua_State *L) {
|
|||
}
|
||||
|
||||
|
||||
LUA_API void lua_getregistry (lua_State *L) {
|
||||
lua_lock(L);
|
||||
sethvalue(L->top, G(L)->registry);
|
||||
api_incr_top(L);
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_getweakregistry (lua_State *L) {
|
||||
lua_lock(L);
|
||||
sethvalue(L->top, G(L)->weakregistry);
|
||||
api_incr_top(L);
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** set functions (stack -> Lua)
|
||||
|
@ -483,26 +460,25 @@ LUA_API void lua_setglobals (lua_State *L) {
|
|||
|
||||
LUA_API int lua_ref (lua_State *L, int lock) {
|
||||
int ref;
|
||||
if (lock == 0) lua_error(L, l_s("unlocked references are obsolete"));
|
||||
if (lua_isnil(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
ref = LUA_REFNIL;
|
||||
return LUA_REFNIL;
|
||||
}
|
||||
else {
|
||||
lua_getweakregistry(L);
|
||||
ref = lua_getn(L, -1) + 1;
|
||||
lua_pushvalue(L, -2);
|
||||
lua_rawseti(L, -2, ref);
|
||||
if (lock) {
|
||||
lua_getregistry(L);
|
||||
lua_pushvalue(L, -3);
|
||||
lua_rawseti(L, -2, ref);
|
||||
lua_pop(L, 1); /* remove registry */
|
||||
}
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, 0); /* get first free element */
|
||||
ref = lua_tonumber(L, -1);
|
||||
lua_pop(L, 1); /* remove it from stack */
|
||||
if (ref != 0) { /* some free element? */
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, ref); /* remove it from list */
|
||||
lua_rawseti(L, LUA_REGISTRYINDEX, 0);
|
||||
}
|
||||
else { /* no free elements */
|
||||
ref = lua_getn(L, LUA_REGISTRYINDEX) + 1; /* use next `n' */
|
||||
lua_pushliteral(L, l_s("n"));
|
||||
lua_pushnumber(L, ref);
|
||||
lua_settable(L, -3);
|
||||
lua_pop(L, 2);
|
||||
lua_settable(L, LUA_REGISTRYINDEX); /* n = n+1 */
|
||||
}
|
||||
lua_rawseti(L, LUA_REGISTRYINDEX, ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
@ -661,13 +637,10 @@ LUA_API void lua_error (lua_State *L, const l_char *s) {
|
|||
|
||||
LUA_API void lua_unref (lua_State *L, int ref) {
|
||||
if (ref >= 0) {
|
||||
lua_getregistry(L);
|
||||
lua_pushnil(L);
|
||||
lua_rawseti(L, -2, ref);
|
||||
lua_getweakregistry(L);
|
||||
lua_pushnil(L);
|
||||
lua_rawseti(L, -2, ref);
|
||||
lua_pop(L, 2); /* remove both registries */
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, 0);
|
||||
lua_pushnumber(L, ref);
|
||||
lua_rawseti(L, LUA_REGISTRYINDEX, 0);
|
||||
lua_rawseti(L, LUA_REGISTRYINDEX, ref);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -787,3 +760,22 @@ LUA_API void lua_setweakmode (lua_State *L, int mode) {
|
|||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LUA_API void lua_pushupvalues (lua_State *L) {
|
||||
TObject *func;
|
||||
int n, i;
|
||||
lua_lock(L);
|
||||
func = (L->ci->base - 1);
|
||||
api_check(L, iscfunction(func));
|
||||
n = clvalue(func)->c.nupvalues;
|
||||
if (LUA_MINSTACK+n > lua_stackspace(L))
|
||||
luaD_error(L, l_s("stack overflow"));
|
||||
for (i=0; i<n; i++) {
|
||||
setobj(L->top, &clvalue(func)->c.upvalue[i]);
|
||||
L->top++;
|
||||
}
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
||||
|
|
25
lbaselib.c
25
lbaselib.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lbaselib.c,v 1.41 2001/08/31 19:46:07 roberto Exp $
|
||||
** $Id: lbaselib.c,v 1.43 2001/10/11 21:41:21 roberto Exp $
|
||||
** Basic library
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -363,18 +363,8 @@ static int luaB_require (lua_State *L) {
|
|||
lua_pushvalue(L, -1); /* duplicate to leave a copy on stack */
|
||||
lua_setglobal(L, LUA_PATH);
|
||||
}
|
||||
lua_getregistry(L);
|
||||
lua_pushliteral(L, LUA_PATH);
|
||||
lua_gettable(L, 3); /* get book-keeping table */
|
||||
if (lua_isnil(L, 4)) { /* no book-keeping table? */
|
||||
lua_pop(L, 1); /* pop the `nil' */
|
||||
lua_newtable(L); /* create book-keeping table */
|
||||
lua_pushliteral(L, LUA_PATH);
|
||||
lua_pushvalue(L, -2); /* duplicate table to leave a copy on stack */
|
||||
lua_settable(L, 3); /* store book-keeping table in registry */
|
||||
}
|
||||
lua_pushvalue(L, 1);
|
||||
lua_gettable(L, 4); /* check package's name in book-keeping table */
|
||||
lua_pushvalue(L, 1); /* check package's name in book-keeping table */
|
||||
lua_gettable(L, lua_upvalueindex(1));
|
||||
if (!lua_isnil(L, -1)) /* is it there? */
|
||||
return 0; /* package is already loaded */
|
||||
else { /* must load it */
|
||||
|
@ -385,7 +375,7 @@ static int luaB_require (lua_State *L) {
|
|||
lua_pushvalue(L, 1); /* package name */
|
||||
lua_concat(L, 2); /* concat directory with package name */
|
||||
res = lua_dofile(L, lua_tostring(L, -1)); /* try to load it */
|
||||
lua_settop(L, 4); /* pop string and eventual results from dofile */
|
||||
lua_settop(L, 2); /* pop string and eventual results from dofile */
|
||||
if (res == 0) break; /* ok; file done */
|
||||
else if (res != LUA_ERRFILE)
|
||||
lua_error(L, NULL); /* error running package; propagate it */
|
||||
|
@ -397,7 +387,7 @@ static int luaB_require (lua_State *L) {
|
|||
}
|
||||
lua_pushvalue(L, 1);
|
||||
lua_pushnumber(L, 1);
|
||||
lua_settable(L, 4); /* mark it as loaded */
|
||||
lua_settable(L, lua_upvalueindex(1)); /* mark it as loaded */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -713,7 +703,6 @@ static const luaL_reg base_funcs[] = {
|
|||
{l_s("rawgettable"), luaB_rawget}, /* for compatibility 3.2 */
|
||||
{l_s("rawsettable"), luaB_rawset}, /* for compatibility 3.2 */
|
||||
{l_s("rawtype"), luaB_rawtype},
|
||||
{l_s("require"), luaB_require},
|
||||
{l_s("setglobal"), luaB_setglobal},
|
||||
{l_s("settag"), luaB_settype}, /* for compatibility 4.0 */
|
||||
{l_s("settype"), luaB_settype},
|
||||
|
@ -737,6 +726,10 @@ LUALIB_API int lua_baselibopen (lua_State *L) {
|
|||
luaL_openl(L, base_funcs);
|
||||
lua_pushliteral(L, l_s(LUA_VERSION));
|
||||
lua_setglobal(L, l_s("_VERSION"));
|
||||
/* `require' needs an empty table as upvalue */
|
||||
lua_newtable(L);
|
||||
lua_pushcclosure(L, luaB_require, 1);
|
||||
lua_setglobal(L, l_s("require"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
16
ldblib.c
16
ldblib.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: ldblib.c,v 1.37 2001/06/06 18:00:19 roberto Exp $
|
||||
** $Id: ldblib.c,v 1.38 2001/08/31 19:46:07 roberto Exp $
|
||||
** Interface from Lua to its debug API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -116,16 +116,14 @@ static int setlocal (lua_State *L) {
|
|||
|
||||
|
||||
static void hookf (lua_State *L, const l_char *key) {
|
||||
lua_getregistry(L);
|
||||
lua_pushstring(L, key);
|
||||
lua_gettable(L, -2);
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
if (lua_isfunction(L, -1)) {
|
||||
lua_pushvalue(L, -3); /* original argument (below table and function) */
|
||||
lua_pushvalue(L, -2); /* original argument (below function) */
|
||||
lua_rawcall(L, 1, 0);
|
||||
}
|
||||
else
|
||||
lua_pop(L, 1); /* pop result from gettable */
|
||||
lua_pop(L, 1); /* pop table */
|
||||
}
|
||||
|
||||
|
||||
|
@ -150,13 +148,11 @@ static void sethook (lua_State *L, const l_char *key, lua_Hook hook,
|
|||
(*sethookf)(L, hook);
|
||||
else
|
||||
luaL_argerror(L, 1, l_s("function expected"));
|
||||
lua_getregistry(L);
|
||||
lua_pushstring(L, key);
|
||||
lua_pushvalue(L, -1); /* dup key */
|
||||
lua_gettable(L, -3); /* get old value */
|
||||
lua_pushvalue(L, -2); /* key (again) */
|
||||
lua_gettable(L, LUA_REGISTRYINDEX); /* get old value */
|
||||
lua_pushstring(L, key);
|
||||
lua_pushvalue(L, 1);
|
||||
lua_settable(L, -5); /* set new value */
|
||||
lua_settable(L, LUA_REGISTRYINDEX); /* set new value */
|
||||
}
|
||||
|
||||
|
||||
|
|
13
ldo.c
13
ldo.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: ldo.c,v 1.141 2001/09/25 17:05:49 roberto Exp $
|
||||
** $Id: ldo.c,v 1.142 2001/10/02 16:45:03 roberto Exp $
|
||||
** Stack and Call structure of Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -44,7 +44,8 @@ void luaD_init (lua_State *L, int stacksize) {
|
|||
stacksize += EXTRA_STACK;
|
||||
L->stack = luaM_newvector(L, stacksize, TObject);
|
||||
L->stacksize = stacksize;
|
||||
L->basefunc.base = L->top = L->stack;
|
||||
setnilvalue(L->stack); /* the `initial' function */
|
||||
L->top = L->basefunc.base = L->stack + 1;
|
||||
restore_stack_limit(L);
|
||||
}
|
||||
|
||||
|
@ -119,12 +120,12 @@ static void luaD_callHook (lua_State *L, lua_Hook callhook,
|
|||
|
||||
|
||||
static StkId callCclosure (lua_State *L, const struct CClosure *cl) {
|
||||
int nup = cl->nupvalues; /* number of upvalues */
|
||||
int n;
|
||||
luaD_checkstack(L, nup+LUA_MINSTACK); /* ensure minimum stack size */
|
||||
for (n=0; n<nup; n++) /* copy upvalues as extra arguments */
|
||||
setobj(L->top++, &cl->upvalue[n]);
|
||||
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
|
||||
lua_unlock(L);
|
||||
#if LUA_COMPATUPVALUES
|
||||
lua_pushupvalues(L);
|
||||
#endif
|
||||
n = (*cl->f)(L); /* do the actual call */
|
||||
lua_lock(L);
|
||||
return L->top - n; /* return index of first result */
|
||||
|
|
5
lgc.c
5
lgc.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lgc.c,v 1.111 2001/09/07 17:39:10 roberto Exp $
|
||||
** $Id: lgc.c,v 1.112 2001/10/02 16:45:03 roberto Exp $
|
||||
** Garbage Collector
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -171,8 +171,7 @@ static void markall (lua_State *L) {
|
|||
marktagmethods(G(L), &st); /* mark tag methods */
|
||||
markstacks(L, &st); /* mark all stacks */
|
||||
marktable(&st, G(L)->type2tag);
|
||||
marktable(&st, G(L)->registry);
|
||||
marktable(&st, G(L)->weakregistry);
|
||||
markobject(&st, &G(L)->registry);
|
||||
while (st.tmark) { /* mark tables */
|
||||
Hash *h = st.tmark; /* get first table from list */
|
||||
st.tmark = h->mark; /* remove it from list */
|
||||
|
|
7
lstate.c
7
lstate.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lstate.c,v 1.66 2001/07/17 17:54:46 roberto Exp $
|
||||
** $Id: lstate.c,v 1.68 2001/09/07 17:39:10 roberto Exp $
|
||||
** Global State
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -66,10 +66,7 @@ static void f_luaopen (lua_State *L, void *ud) {
|
|||
luaD_init(L, so->stacksize); /* init stack */
|
||||
L->gt = luaH_new(L, 10); /* table of globals */
|
||||
G(L)->type2tag = luaH_new(L, 10);
|
||||
G(L)->registry = luaH_new(L, 0);
|
||||
G(L)->weakregistry = luaH_new(L, 0);
|
||||
/* make weakregistry weak */
|
||||
G(L)->weakregistry->weakmode = LUA_WEAK_KEY | LUA_WEAK_VALUE;
|
||||
sethvalue(&G(L)->registry, luaH_new(L, 0));
|
||||
luaS_resize(L, MINPOWER2);
|
||||
luaX_init(L);
|
||||
luaT_init(L);
|
||||
|
|
5
lstate.h
5
lstate.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lstate.h,v 1.59 2001/09/07 17:39:10 roberto Exp $
|
||||
** $Id: lstate.h,v 1.60 2001/10/02 16:43:29 roberto Exp $
|
||||
** Global State
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -58,8 +58,7 @@ typedef struct global_State {
|
|||
size_t Mbuffsize; /* size of Mbuffer */
|
||||
stringtable strt; /* hash table for strings */
|
||||
Hash *type2tag; /* hash table from type names to tags */
|
||||
Hash *registry; /* (strong) registry table */
|
||||
Hash *weakregistry; /* weakregistry table */
|
||||
TObject registry; /* registry table */
|
||||
struct TM *TMtable; /* table for tag methods */
|
||||
int sizeTM; /* size of TMtable */
|
||||
int ntag; /* number of tags in TMtable */
|
||||
|
|
21
ltests.c
21
ltests.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: ltests.c,v 1.91 2001/09/07 17:39:10 roberto Exp $
|
||||
** $Id: ltests.c,v 1.92 2001/10/02 16:45:03 roberto Exp $
|
||||
** Internal Module for Debugging of the Lua Implementation
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -317,21 +317,16 @@ static int tref (lua_State *L) {
|
|||
int level = lua_gettop(L);
|
||||
luaL_checkany(L, 1);
|
||||
lua_pushvalue(L, 1);
|
||||
lua_pushnumber(L, lua_ref(L, luaL_opt_int(L, 2, 1)));
|
||||
lua_pushnumber(L, lua_ref(L, 1));
|
||||
assert(lua_gettop(L) == level+1); /* +1 for result */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int getref (lua_State *L) {
|
||||
int level = lua_gettop(L);
|
||||
if (lua_getref(L, luaL_check_int(L, 1))) {
|
||||
assert(lua_gettop(L) == level+1);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
assert(lua_gettop(L) == level);
|
||||
return 0;
|
||||
}
|
||||
lua_getref(L, luaL_check_int(L, 1));
|
||||
assert(lua_gettop(L) == level+1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int unref (lua_State *L) {
|
||||
|
@ -570,6 +565,12 @@ static int testC (lua_State *L) {
|
|||
else if EQ(l_s("pushvalue")) {
|
||||
lua_pushvalue(L, getnum);
|
||||
}
|
||||
else if EQ(l_s("pushcclosure")) {
|
||||
lua_pushcclosure(L, testC, getnum);
|
||||
}
|
||||
else if EQ(l_s("pushupvalues")) {
|
||||
lua_pushupvalues(L);
|
||||
}
|
||||
else if EQ(l_s("remove")) {
|
||||
lua_remove(L, getnum);
|
||||
}
|
||||
|
|
4
lua.c
4
lua.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lua.c,v 1.69 2001/08/30 20:54:02 roberto Exp $
|
||||
** $Id: lua.c,v 1.70 2001/09/25 17:06:34 roberto Exp $
|
||||
** Lua stand-alone interpreter
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -141,7 +141,7 @@ static void getargs (l_char *argv[]) {
|
|||
|
||||
|
||||
static int l_getargs (lua_State *l) {
|
||||
l_char **argv = (l_char **)lua_touserdata(l, -1);
|
||||
l_char **argv = (l_char **)lua_touserdata(l, lua_upvalueindex(1));
|
||||
getargs(argv);
|
||||
return 1;
|
||||
}
|
||||
|
|
18
lua.h
18
lua.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lua.h,v 1.103 2001/08/31 19:46:07 roberto Exp $
|
||||
** $Id: lua.h,v 1.104 2001/10/11 21:41:21 roberto Exp $
|
||||
** Lua - An Extensible Extension Language
|
||||
** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
|
||||
** e-mail: info@lua.org
|
||||
|
@ -35,6 +35,13 @@
|
|||
#define LUA_MULTRET (-1)
|
||||
|
||||
|
||||
/* pseudo-index for registry */
|
||||
#define LUA_REGISTRYINDEX (-10000)
|
||||
|
||||
/* pseudo-indices for upvalues */
|
||||
#define lua_upvalueindex(i) (LUA_REGISTRYINDEX-(i))
|
||||
|
||||
|
||||
/* error codes for `lua_do*' and the like */
|
||||
#define LUA_ERRRUN 1
|
||||
#define LUA_ERRFILE 2
|
||||
|
@ -160,9 +167,7 @@ LUA_API void lua_rawget (lua_State *L, int index);
|
|||
LUA_API void lua_rawgeti (lua_State *L, int index, int n);
|
||||
LUA_API void lua_getglobals (lua_State *L);
|
||||
LUA_API void lua_gettagmethod (lua_State *L, int tag, const lua_char *event);
|
||||
LUA_API int lua_getref (lua_State *L, int ref);
|
||||
LUA_API void lua_newtable (lua_State *L);
|
||||
LUA_API void lua_getregistry (lua_State *L);
|
||||
LUA_API void lua_getweakregistry (lua_State *L);
|
||||
|
||||
|
||||
|
@ -246,14 +251,19 @@ LUA_API int lua_getweakmode (lua_State *L, int index);
|
|||
#define lua_pushliteral(L, s) lua_pushlstring(L, s, \
|
||||
(sizeof(s)/sizeof(lua_char))-1)
|
||||
|
||||
#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX);
|
||||
|
||||
#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, ref)
|
||||
|
||||
|
||||
/*
|
||||
** compatibility macros
|
||||
** compatibility macros and functions
|
||||
*/
|
||||
#define lua_newtag(L) lua_newtype(L, NULL, LUA_TNONE)
|
||||
#define lua_typename lua_tag2name
|
||||
|
||||
LUA_API void lua_pushupvalues (lua_State *L);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue