forked from enlightenment/efl
elua: use Eina_File (mmap)
This commit is contained in:
parent
26dc3505bc
commit
063dd4147e
|
@ -10,32 +10,31 @@
|
||||||
|
|
||||||
/* bytecode caching */
|
/* bytecode caching */
|
||||||
|
|
||||||
static int check_bc(const char *fname, const char *mode, Eina_Bool *bc) {
|
static Eina_File *check_bc(Eina_File *of, const char *mode, Eina_Bool *bc) {
|
||||||
const char *ext = strstr(fname, ".lua");
|
const char *fname = eina_file_filename_get(of);
|
||||||
|
const char *ext = strstr(fname, ".lua");
|
||||||
if (ext && !ext[4] && (!mode || strchr(mode, 't'))) {
|
if (ext && !ext[4] && (!mode || strchr(mode, 't'))) {
|
||||||
/* loading lua source file, try cached */
|
/* loading lua source file, try cached */
|
||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
snprintf(buf, sizeof(buf), "%sc", fname);
|
snprintf(buf, sizeof(buf), "%sc", fname);
|
||||||
int fd = open(buf, O_RDONLY);
|
Eina_File *f = eina_file_open(buf, EINA_FALSE);
|
||||||
if (fd < 0) {
|
if (!f) {
|
||||||
/* no cached bytecode */
|
/* no cached bytecode */
|
||||||
*bc = EINA_TRUE;
|
*bc = EINA_TRUE;
|
||||||
} else {
|
} else {
|
||||||
/* cached bytecode, check timestamp */
|
/* cached bytecode, check timestamps */
|
||||||
struct stat s1, s2;
|
if (eina_file_mtime_get(f) > eina_file_mtime_get(of)) {
|
||||||
stat(fname, &s1);
|
|
||||||
stat(buf, &s2);
|
|
||||||
if (s2.st_ctime > s1.st_ctime) {
|
|
||||||
/* bytecode new enough, chunkname stays the same */
|
/* bytecode new enough, chunkname stays the same */
|
||||||
return fd;
|
eina_file_close(of);
|
||||||
|
return f;
|
||||||
} else {
|
} else {
|
||||||
/* bytecode too old, remove old file */
|
/* bytecode too old, remove old file */
|
||||||
close(fd);
|
eina_file_close(f);
|
||||||
*bc = EINA_TRUE;
|
*bc = EINA_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return of;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int writef(lua_State *L EINA_UNUSED, const void *p, size_t size,
|
static int writef(lua_State *L EINA_UNUSED, const void *p, size_t size,
|
||||||
|
@ -56,111 +55,69 @@ static void write_bc(lua_State *L, const char *fname) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* loadfile - regular version */
|
|
||||||
|
|
||||||
typedef struct Cached_Stream {
|
|
||||||
FILE *f;
|
|
||||||
char buff[LUAL_BUFFERSIZE];
|
|
||||||
} Cached_Stream;
|
|
||||||
|
|
||||||
static const char *getf(lua_State *L EINA_UNUSED, void *ud, size_t *size) {
|
static const char *getf(lua_State *L EINA_UNUSED, void *ud, size_t *size) {
|
||||||
Cached_Stream *s = ud;
|
char *buff = *((char**)ud);
|
||||||
if (feof(s->f)) return NULL;
|
if (feof(stdin)) return NULL;
|
||||||
*size = fread(s->buff, 1, sizeof(s->buff), s->f);
|
*size = fread(buff, 1, LUAL_BUFFERSIZE, stdin);
|
||||||
return (*size > 0) ? s->buff : NULL;
|
return (*size > 0) ? buff : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int elua_loadfilex(lua_State *L, const char *fname, const char *mode) {
|
static int elua_loadstdin(lua_State *L, const char *mode) {
|
||||||
Cached_Stream s;
|
char buff[LUAL_BUFFERSIZE];
|
||||||
int status;
|
int status = lua_loadx(L, getf, &buff, "=stdin", mode);
|
||||||
const char *chname;
|
if (ferror(stdin)) {
|
||||||
Eina_Bool bcache = EINA_FALSE;
|
|
||||||
if (!fname) {
|
|
||||||
s.f = stdin;
|
|
||||||
chname = "=stdin";
|
|
||||||
} else {
|
|
||||||
if (!(s.f = fopen(fname, "rb"))) {
|
|
||||||
lua_pushfstring(L, "cannot open %s: %s", fname, strerror(errno));
|
|
||||||
return LUA_ERRFILE;
|
|
||||||
}
|
|
||||||
chname = lua_pushfstring(L, "@%s", fname);
|
|
||||||
int fd = check_bc(fname, mode, &bcache);
|
|
||||||
if (fd >= 0) {
|
|
||||||
fclose(s.f);
|
|
||||||
s.f = fdopen(fd, "rb");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
status = lua_loadx(L, getf, &s, chname, mode);
|
|
||||||
if (ferror(s.f)) {
|
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
lua_pushfstring(L, "cannot read %s: %s", chname + 1, strerror(errno));
|
lua_pushfstring(L, "cannot read stdin: %s", strerror(errno));
|
||||||
if (fname) {
|
|
||||||
lua_remove(L, -2);
|
|
||||||
fclose(s.f);
|
|
||||||
}
|
|
||||||
return LUA_ERRFILE;
|
return LUA_ERRFILE;
|
||||||
}
|
}
|
||||||
/* trigger bytecode writing */
|
|
||||||
if (!status && bcache) write_bc(L, fname);
|
|
||||||
if (fname) {
|
|
||||||
lua_remove(L, -2);
|
|
||||||
fclose(s.f);
|
|
||||||
}
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
int elua_loadfile(lua_State *L, const char *fname) {
|
|
||||||
return elua_loadfilex(L, fname, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* loadfile - mmap version */
|
|
||||||
|
|
||||||
typedef struct Map_Stream {
|
typedef struct Map_Stream {
|
||||||
char *fmap;
|
char *fmap;
|
||||||
size_t flen;
|
size_t flen;
|
||||||
} Map_Stream;
|
} Map_Stream;
|
||||||
|
|
||||||
static const char *getf_map(lua_State *L EINA_UNUSED, void *ud, size_t *size) {
|
static const char *getf_map(lua_State *L EINA_UNUSED, void *ud, size_t *size) {
|
||||||
Map_Stream *s = ud;
|
Map_Stream *s = ud;
|
||||||
|
const char *fmap = s->fmap;
|
||||||
*size = s->flen;
|
*size = s->flen;
|
||||||
return s->fmap;
|
/* gotta null it - tell luajit to terminate reading */
|
||||||
|
s->fmap = NULL;
|
||||||
|
return fmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
int elua_loadfilex_mmap(lua_State *L, const char *fname, const char *mode) {
|
int elua_loadfilex(lua_State *L, const char *fname, const char *mode) {
|
||||||
Map_Stream s;
|
Map_Stream s;
|
||||||
int status, fd, nfd;
|
int status;
|
||||||
|
Eina_File *f;
|
||||||
const char *chname;
|
const char *chname;
|
||||||
Eina_Bool bcache = EINA_FALSE;
|
Eina_Bool bcache = EINA_FALSE;
|
||||||
if (!fname) {
|
if (!fname) {
|
||||||
return elua_loadfilex(L, fname, mode);
|
return elua_loadstdin(L, mode);
|
||||||
}
|
}
|
||||||
if ((fd = open(fname, O_RDONLY, 0)) < 0) {
|
if (!(f = eina_file_open(fname, EINA_FALSE))) {
|
||||||
lua_pushfstring(L, "cannot open %s: %s", fname, strerror(errno));
|
lua_pushfstring(L, "cannot open %s: %s", fname, strerror(errno));
|
||||||
return LUA_ERRFILE;
|
return LUA_ERRFILE;
|
||||||
}
|
}
|
||||||
chname = lua_pushfstring(L, "@%s", fname);
|
chname = lua_pushfstring(L, "@%s", fname);
|
||||||
if ((nfd = check_bc(fname, mode, &bcache)) > 0) {
|
f = check_bc(f, mode, &bcache);
|
||||||
close(fd);
|
s.flen = eina_file_size_get(f);
|
||||||
fd = nfd;
|
if (!(s.fmap = eina_file_map_all(f, EINA_FILE_RANDOM))) {
|
||||||
}
|
|
||||||
s.flen = lseek(fd, 0, SEEK_END);
|
|
||||||
lseek(fd, 0, SEEK_SET);
|
|
||||||
if ((s.fmap = mmap(NULL, s.flen, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0))
|
|
||||||
== MAP_FAILED) {
|
|
||||||
lua_pushfstring(L, "cannot read %s: %s", chname + 1, strerror(errno));
|
lua_pushfstring(L, "cannot read %s: %s", chname + 1, strerror(errno));
|
||||||
lua_remove(L, -2);
|
lua_remove(L, -2);
|
||||||
return LUA_ERRFILE;
|
return LUA_ERRFILE;
|
||||||
}
|
}
|
||||||
status = lua_loadx(L, getf_map, &s, chname, mode);
|
status = lua_loadx(L, getf_map, &s, chname, mode);
|
||||||
munmap(s.fmap, s.flen);
|
eina_file_map_free(f, s.fmap);
|
||||||
close(fd);
|
eina_file_close(f);
|
||||||
if (!status && bcache) write_bc(L, fname);
|
if (!status && bcache) write_bc(L, fname);
|
||||||
lua_remove(L, -2);
|
lua_remove(L, -2);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
int elua_loadfile_mmap(lua_State *L, const char *fname) {
|
int elua_loadfile(lua_State *L, const char *fname) {
|
||||||
return elua_loadfilex_mmap(L, fname, NULL);
|
return elua_loadfilex(L, fname, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* lua function */
|
/* lua function */
|
||||||
|
@ -168,12 +125,8 @@ int elua_loadfile_mmap(lua_State *L, const char *fname) {
|
||||||
static int loadfile(lua_State *L) {
|
static int loadfile(lua_State *L) {
|
||||||
const char *fname = luaL_optstring(L, 1, NULL);
|
const char *fname = luaL_optstring(L, 1, NULL);
|
||||||
const char *mode = luaL_optstring(L, 2, NULL);
|
const char *mode = luaL_optstring(L, 2, NULL);
|
||||||
int status, hasenv = (lua_gettop(L) >= 3);
|
int status = elua_loadfilex(L, fname, mode),
|
||||||
if (lua_toboolean(L, 4)) {
|
hasenv = (lua_gettop(L) >= 3);
|
||||||
status = elua_loadfilex_mmap(L, fname, mode);
|
|
||||||
} else {
|
|
||||||
status = elua_loadfilex(L, fname, mode);
|
|
||||||
}
|
|
||||||
if (!status) {
|
if (!status) {
|
||||||
if (hasenv) {
|
if (hasenv) {
|
||||||
lua_pushvalue(L, 3);
|
lua_pushvalue(L, 3);
|
||||||
|
|
|
@ -229,7 +229,10 @@ static int lua_main(lua_State *L) {
|
||||||
|
|
||||||
luaL_openlibs(L);
|
luaL_openlibs(L);
|
||||||
|
|
||||||
elua_loadfile(L, ELUA_DATA_DIR "/core/module.lua");
|
if (report(L, elua_loadfile(L, ELUA_DATA_DIR "/core/module.lua"))) {
|
||||||
|
m->status = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
lua_pushcfunction(L, register_require);
|
lua_pushcfunction(L, register_require);
|
||||||
lua_createtable(L, 0, 0);
|
lua_createtable(L, 0, 0);
|
||||||
luaL_register(L, NULL, utillib);
|
luaL_register(L, NULL, utillib);
|
||||||
|
|
|
@ -30,8 +30,6 @@ extern int el_log_domain;
|
||||||
|
|
||||||
int elua_loadfilex(lua_State *L, const char *fname, const char *mode);
|
int elua_loadfilex(lua_State *L, const char *fname, const char *mode);
|
||||||
int elua_loadfile(lua_State *L, const char *fname);
|
int elua_loadfile(lua_State *L, const char *fname);
|
||||||
int elua_loadfilex_mmap(lua_State *L, const char *fname, const char *mode);
|
|
||||||
int elua_loadfile_mmap(lua_State *L, const char *fname);
|
|
||||||
void elua_register_cache(lua_State *L);
|
void elua_register_cache(lua_State *L);
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue