summaryrefslogtreecommitdiff
path: root/src/lib_package.c
diff options
context:
space:
mode:
authorMike Pall <mike>2011-08-17 00:10:12 +0200
committerMike Pall <mike>2011-08-17 00:10:12 +0200
commitaad7ea3c02b0baed5b700565eea36c9b33d7c6b1 (patch)
tree128a3d419820cc65c9e83de84dc9c4745bf4b083 /src/lib_package.c
parentb500b50edc0d421e72a1126620fbe99e822d05ba (diff)
downloadluajit-aad7ea3c02b0baed5b700565eea36c9b33d7c6b1.tar.gz
luajit-aad7ea3c02b0baed5b700565eea36c9b33d7c6b1.tar.bz2
luajit-aad7ea3c02b0baed5b700565eea36c9b33d7c6b1.zip
Load embedded bytecode with require().
Diffstat (limited to 'src/lib_package.c')
-rw-r--r--src/lib_package.c106
1 files changed, 81 insertions, 25 deletions
diff --git a/src/lib_package.c b/src/lib_package.c
index 71e0826b..cb5f64e7 100644
--- a/src/lib_package.c
+++ b/src/lib_package.c
@@ -22,11 +22,16 @@
22/* Error codes for ll_loadfunc. */ 22/* Error codes for ll_loadfunc. */
23#define PACKAGE_ERR_LIB 1 23#define PACKAGE_ERR_LIB 1
24#define PACKAGE_ERR_FUNC 2 24#define PACKAGE_ERR_FUNC 2
25#define PACKAGE_ERR_LOAD 3
25 26
26/* Redefined in platform specific part. */ 27/* Redefined in platform specific part. */
27#define PACKAGE_LIB_FAIL "open" 28#define PACKAGE_LIB_FAIL "open"
28#define setprogdir(L) ((void)0) 29#define setprogdir(L) ((void)0)
29 30
31/* Symbol name prefixes. */
32#define SYMPREFIX_CF "luaopen_%s"
33#define SYMPREFIX_BC "luaJIT_BC_%s"
34
30#if LJ_TARGET_DLOPEN 35#if LJ_TARGET_DLOPEN
31 36
32#include <dlfcn.h> 37#include <dlfcn.h>
@@ -50,11 +55,29 @@ static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym)
50 return f; 55 return f;
51} 56}
52 57
58static const char *ll_bcsym(void *lib, const char *sym)
59{
60#if defined(RTLD_DEFAULT)
61 if (lib == NULL) lib = RTLD_DEFAULT;
62#elif LJ_TARGET_OSX || LJ_TARGET_BSD
63 if (lib == NULL) lib = (void *)(intptr_t)-2;
64#endif
65 return (const char *)dlsym(lib, sym);
66}
67
53#elif LJ_TARGET_WINDOWS 68#elif LJ_TARGET_WINDOWS
54 69
55#define WIN32_LEAN_AND_MEAN 70#define WIN32_LEAN_AND_MEAN
71#ifndef WINVER
72#define WINVER 0x0500
73#endif
56#include <windows.h> 74#include <windows.h>
57 75
76#ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
77#define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 4
78BOOL WINAPI GetModuleHandleExA(DWORD, LPCSTR, HMODULE*);
79#endif
80
58#undef setprogdir 81#undef setprogdir
59 82
60static void setprogdir(lua_State *L) 83static void setprogdir(lua_State *L)
@@ -102,6 +125,20 @@ static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym)
102 return f; 125 return f;
103} 126}
104 127
128static const char *ll_bcsym(void *lib, const char *sym)
129{
130 if (lib) {
131 return (const char *)GetProcAddress((HINSTANCE)lib, sym);
132 } else {
133 HINSTANCE h = GetModuleHandle(NULL);
134 const char *p = (const char *)GetProcAddress(h, sym);
135 if (p == NULL && GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
136 (const char *)ll_bcsym, &h))
137 p = (const char *)GetProcAddress(h, sym);
138 return p;
139 }
140}
141
105#else 142#else
106 143
107#undef PACKAGE_LIB_FAIL 144#undef PACKAGE_LIB_FAIL
@@ -127,6 +164,13 @@ static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym)
127 lua_pushliteral(L, DLMSG); 164 lua_pushliteral(L, DLMSG);
128 return NULL; 165 return NULL;
129} 166}
167
168static const char *ll_bcsym(void *lib, const char *sym)
169{
170 (void)lib; (void)sym;
171 return NULL;
172}
173
130#endif 174#endif
131 175
132/* ------------------------------------------------------------------------ */ 176/* ------------------------------------------------------------------------ */
@@ -151,18 +195,41 @@ static void **ll_register(lua_State *L, const char *path)
151 return plib; 195 return plib;
152} 196}
153 197
154static int ll_loadfunc(lua_State *L, const char *path, const char *sym) 198static const char *mksymname(lua_State *L, const char *modname,
199 const char *prefix)
200{
201 const char *funcname;
202 const char *mark = strchr(modname, *LUA_IGMARK);
203 if (mark) modname = mark + 1;
204 funcname = luaL_gsub(L, modname, ".", "_");
205 funcname = lua_pushfstring(L, prefix, funcname);
206 lua_remove(L, -2); /* remove 'gsub' result */
207 return funcname;
208}
209
210static int ll_loadfunc(lua_State *L, const char *path, const char *name, int r)
155{ 211{
156 void **reg = ll_register(L, path); 212 void **reg = ll_register(L, path);
157 if (*reg == NULL) *reg = ll_load(L, path); 213 if (*reg == NULL) *reg = ll_load(L, path);
158 if (*reg == NULL) { 214 if (*reg == NULL) {
159 return PACKAGE_ERR_LIB; /* unable to load library */ 215 return PACKAGE_ERR_LIB; /* unable to load library */
160 } else { 216 } else {
217 const char *sym = r ? name : mksymname(L, name, SYMPREFIX_CF);
161 lua_CFunction f = ll_sym(L, *reg, sym); 218 lua_CFunction f = ll_sym(L, *reg, sym);
162 if (f == NULL) 219 if (f) {
163 return PACKAGE_ERR_FUNC; /* unable to find function */ 220 lua_pushcfunction(L, f);
164 lua_pushcfunction(L, f); 221 return 0;
165 return 0; /* return function */ 222 }
223 if (!r) {
224 const char *bcdata = ll_bcsym(*reg, mksymname(L, name, SYMPREFIX_BC));
225 lua_pop(L, 1);
226 if (bcdata) {
227 if (luaL_loadbuffer(L, bcdata, ~(size_t)0, name) != 0)
228 return PACKAGE_ERR_LOAD;
229 return 0;
230 }
231 }
232 return PACKAGE_ERR_FUNC; /* unable to find function */
166 } 233 }
167} 234}
168 235
@@ -170,7 +237,7 @@ static int lj_cf_package_loadlib(lua_State *L)
170{ 237{
171 const char *path = luaL_checkstring(L, 1); 238 const char *path = luaL_checkstring(L, 1);
172 const char *init = luaL_checkstring(L, 2); 239 const char *init = luaL_checkstring(L, 2);
173 int st = ll_loadfunc(L, path, init); 240 int st = ll_loadfunc(L, path, init, 1);
174 if (st == 0) { /* no errors? */ 241 if (st == 0) { /* no errors? */
175 return 1; /* return the loaded function */ 242 return 1; /* return the loaded function */
176 } else { /* error; error message is on stack top */ 243 } else { /* error; error message is on stack top */
@@ -268,32 +335,18 @@ static int lj_cf_package_loader_lua(lua_State *L)
268 return 1; /* library loaded successfully */ 335 return 1; /* library loaded successfully */
269} 336}
270 337
271static const char *mkfuncname(lua_State *L, const char *modname)
272{
273 const char *funcname;
274 const char *mark = strchr(modname, *LUA_IGMARK);
275 if (mark) modname = mark + 1;
276 funcname = luaL_gsub(L, modname, ".", "_");
277 funcname = lua_pushfstring(L, "luaopen_%s", funcname);
278 lua_remove(L, -2); /* remove 'gsub' result */
279 return funcname;
280}
281
282static int lj_cf_package_loader_c(lua_State *L) 338static int lj_cf_package_loader_c(lua_State *L)
283{ 339{
284 const char *funcname;
285 const char *name = luaL_checkstring(L, 1); 340 const char *name = luaL_checkstring(L, 1);
286 const char *filename = findfile(L, name, "cpath"); 341 const char *filename = findfile(L, name, "cpath");
287 if (filename == NULL) return 1; /* library not found in this path */ 342 if (filename == NULL) return 1; /* library not found in this path */
288 funcname = mkfuncname(L, name); 343 if (ll_loadfunc(L, filename, name, 0) != 0)
289 if (ll_loadfunc(L, filename, funcname) != 0)
290 loaderror(L, filename); 344 loaderror(L, filename);
291 return 1; /* library loaded successfully */ 345 return 1; /* library loaded successfully */
292} 346}
293 347
294static int lj_cf_package_loader_croot(lua_State *L) 348static int lj_cf_package_loader_croot(lua_State *L)
295{ 349{
296 const char *funcname;
297 const char *filename; 350 const char *filename;
298 const char *name = luaL_checkstring(L, 1); 351 const char *name = luaL_checkstring(L, 1);
299 const char *p = strchr(name, '.'); 352 const char *p = strchr(name, '.');
@@ -302,8 +355,7 @@ static int lj_cf_package_loader_croot(lua_State *L)
302 lua_pushlstring(L, name, (size_t)(p - name)); 355 lua_pushlstring(L, name, (size_t)(p - name));
303 filename = findfile(L, lua_tostring(L, -1), "cpath"); 356 filename = findfile(L, lua_tostring(L, -1), "cpath");
304 if (filename == NULL) return 1; /* root not found */ 357 if (filename == NULL) return 1; /* root not found */
305 funcname = mkfuncname(L, name); 358 if ((st = ll_loadfunc(L, filename, name, 0)) != 0) {
306 if ((st = ll_loadfunc(L, filename, funcname)) != 0) {
307 if (st != PACKAGE_ERR_FUNC) loaderror(L, filename); /* real error */ 359 if (st != PACKAGE_ERR_FUNC) loaderror(L, filename); /* real error */
308 lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, 360 lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
309 name, filename); 361 name, filename);
@@ -319,8 +371,12 @@ static int lj_cf_package_loader_preload(lua_State *L)
319 if (!lua_istable(L, -1)) 371 if (!lua_istable(L, -1))
320 luaL_error(L, LUA_QL("package.preload") " must be a table"); 372 luaL_error(L, LUA_QL("package.preload") " must be a table");
321 lua_getfield(L, -1, name); 373 lua_getfield(L, -1, name);
322 if (lua_isnil(L, -1)) /* not found? */ 374 if (lua_isnil(L, -1)) { /* Not found? */
323 lua_pushfstring(L, "\n\tno field package.preload['%s']", name); 375 const char *bcname = mksymname(L, name, SYMPREFIX_BC);
376 const char *bcdata = ll_bcsym(NULL, bcname);
377 if (bcdata == NULL || luaL_loadbuffer(L, bcdata, ~(size_t)0, name) != 0)
378 lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
379 }
324 return 1; 380 return 1;
325} 381}
326 382