Created
March 20, 2014 03:55
-
-
Save cloudwu/9656890 to your computer and use it in GitHub Desktop.
use lua_clonefunction for fast lua file load
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment