mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-22 02:53:09 +00:00
use lua_clonefunction for load lua file
This commit is contained in:
@@ -1,2 +1,5 @@
|
||||
Copy from Lua 5.3.0 final http://www.lua.org/ftp/lua-5.3.0.tar.gz
|
||||
This is a modify version of lua 5.3.0 (http://www.lua.org/ftp/lua-5.3.0.tar.gz) .
|
||||
|
||||
For detail : http://lua-users.org/lists/lua-l/2014-03/msg00489.html
|
||||
|
||||
|
||||
|
||||
@@ -1011,7 +1011,7 @@ static Proto * cloneproto (lua_State *L, const Proto *src) {
|
||||
return f;
|
||||
}
|
||||
|
||||
LUA_API void lua_clonefunction (lua_State *L, void * fp) {
|
||||
LUA_API void lua_clonefunction (lua_State *L, const void * fp) {
|
||||
LClosure *cl;
|
||||
LClosure *f = cast(LClosure *, fp);
|
||||
lua_lock(L);
|
||||
@@ -1027,13 +1027,13 @@ LUA_API void lua_clonefunction (lua_State *L, void * fp) {
|
||||
api_incr_top(L);
|
||||
luaF_initupvals(L, cl);
|
||||
|
||||
if (f->nupvalues >= 1) { /* does it have an upvalue? */
|
||||
if (cl->nupvalues >= 1) { /* does it have an upvalue? */
|
||||
/* get global table from registry */
|
||||
Table *reg = hvalue(&G(L)->l_registry);
|
||||
const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
|
||||
/* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
|
||||
setobj(L, f->upvals[0]->v, gt);
|
||||
luaC_upvalbarrier(L, f->upvals[0]);
|
||||
setobj(L, cl->upvals[0]->v, gt);
|
||||
luaC_upvalbarrier(L, cl->upvals[0]);
|
||||
}
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
@@ -638,7 +638,7 @@ static int skipcomment (LoadF *lf, int *cp) {
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
|
||||
static int luaL_loadfilex_ (lua_State *L, const char *filename,
|
||||
const char *mode) {
|
||||
LoadF lf;
|
||||
int status, readstatus;
|
||||
@@ -970,3 +970,123 @@ LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) {
|
||||
ver, *v);
|
||||
}
|
||||
|
||||
// use clonefunction
|
||||
|
||||
#define LOCK(q) while (__sync_lock_test_and_set(&(q)->lock,1)) {}
|
||||
#define UNLOCK(q) __sync_lock_release(&(q)->lock);
|
||||
|
||||
struct codecache {
|
||||
int lock;
|
||||
lua_State *L;
|
||||
};
|
||||
|
||||
static struct codecache CC = { 0 , NULL };
|
||||
|
||||
static void
|
||||
clearcache() {
|
||||
if (CC.L == NULL)
|
||||
return;
|
||||
LOCK(&CC)
|
||||
lua_close(CC.L);
|
||||
CC.L = luaL_newstate();
|
||||
UNLOCK(&CC)
|
||||
}
|
||||
|
||||
static void
|
||||
init() {
|
||||
CC.lock = 0;
|
||||
CC.L = luaL_newstate();
|
||||
}
|
||||
|
||||
static const void *
|
||||
load(const char *key) {
|
||||
if (CC.L == NULL)
|
||||
return NULL;
|
||||
LOCK(&CC)
|
||||
lua_State *L = CC.L;
|
||||
lua_pushstring(L, key);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
const void * result = lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
UNLOCK(&CC)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static const void *
|
||||
save(const char *key, const void * proto) {
|
||||
lua_State *L;
|
||||
const void * result = NULL;
|
||||
|
||||
LOCK(&CC)
|
||||
if (CC.L == NULL) {
|
||||
init();
|
||||
L = CC.L;
|
||||
} else {
|
||||
L = CC.L;
|
||||
lua_pushstring(L, key);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
result = lua_touserdata(L, -1); /* stack: key oldvalue */
|
||||
if (result == NULL) {
|
||||
lua_pop(L,1);
|
||||
lua_pushlightuserdata(L, (void *)proto);
|
||||
lua_rawset(L, LUA_REGISTRYINDEX);
|
||||
} else {
|
||||
lua_pop(L,2);
|
||||
}
|
||||
}
|
||||
UNLOCK(&CC)
|
||||
return result;
|
||||
}
|
||||
|
||||
LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
|
||||
const char *mode) {
|
||||
const void * proto = load(filename);
|
||||
if (proto) {
|
||||
lua_clonefunction(L, proto);
|
||||
return LUA_OK;
|
||||
}
|
||||
lua_State * eL = luaL_newstate();
|
||||
if (eL == NULL) {
|
||||
lua_pushliteral(L, "New state failed");
|
||||
return LUA_ERRMEM;
|
||||
}
|
||||
int err = luaL_loadfilex_(eL, filename, mode);
|
||||
if (err != LUA_OK) {
|
||||
size_t sz = 0;
|
||||
const char * msg = lua_tolstring(eL, -1, &sz);
|
||||
lua_pushlstring(L, msg, sz);
|
||||
lua_close(eL);
|
||||
return err;
|
||||
}
|
||||
proto = lua_topointer(eL, -1);
|
||||
const void * oldv = save(filename, proto);
|
||||
if (oldv) {
|
||||
lua_close(eL);
|
||||
lua_clonefunction(L, oldv);
|
||||
} else {
|
||||
lua_clonefunction(L, proto);
|
||||
/* Never close it. notice: memory leak */
|
||||
}
|
||||
|
||||
return LUA_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
cache_clear(lua_State *L) {
|
||||
(void)(L);
|
||||
clearcache();
|
||||
return 0;
|
||||
}
|
||||
|
||||
LUAMOD_API int luaopen_cache(lua_State *L) {
|
||||
luaL_Reg l[] = {
|
||||
{ "clear", cache_clear },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
luaL_newlib(L,l);
|
||||
lua_getglobal(L, "loadfile");
|
||||
lua_setfield(L, -2, "loadfile");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -280,6 +280,7 @@ LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
|
||||
|
||||
LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip);
|
||||
|
||||
LUA_API void (lua_clonefunction) (lua_State *L, const void *eL);
|
||||
|
||||
/*
|
||||
** coroutine functions
|
||||
|
||||
Reference in New Issue
Block a user