diff options
| author | Mike Pall <mike> | 2011-08-17 00:10:12 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2011-08-17 00:10:12 +0200 |
| commit | aad7ea3c02b0baed5b700565eea36c9b33d7c6b1 (patch) | |
| tree | 128a3d419820cc65c9e83de84dc9c4745bf4b083 | |
| parent | b500b50edc0d421e72a1126620fbe99e822d05ba (diff) | |
| download | luajit-aad7ea3c02b0baed5b700565eea36c9b33d7c6b1.tar.gz luajit-aad7ea3c02b0baed5b700565eea36c9b33d7c6b1.tar.bz2 luajit-aad7ea3c02b0baed5b700565eea36c9b33d7c6b1.zip | |
Load embedded bytecode with require().
| -rw-r--r-- | src/lib_package.c | 106 | ||||
| -rw-r--r-- | src/lj_bcread.c | 2 | ||||
| -rw-r--r-- | src/lj_clib.c | 2 |
3 files changed, 83 insertions, 27 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 | ||
| 58 | static 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 | ||
| 78 | BOOL WINAPI GetModuleHandleExA(DWORD, LPCSTR, HMODULE*); | ||
| 79 | #endif | ||
| 80 | |||
| 58 | #undef setprogdir | 81 | #undef setprogdir |
| 59 | 82 | ||
| 60 | static void setprogdir(lua_State *L) | 83 | static 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 | ||
| 128 | static 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 | |||
| 168 | static 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 | ||
| 154 | static int ll_loadfunc(lua_State *L, const char *path, const char *sym) | 198 | static 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 | |||
| 210 | static 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 | ||
| 271 | static 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 | |||
| 282 | static int lj_cf_package_loader_c(lua_State *L) | 338 | static 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 | ||
| 294 | static int lj_cf_package_loader_croot(lua_State *L) | 348 | static 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 | ||
diff --git a/src/lj_bcread.c b/src/lj_bcread.c index c5d4cd9d..30479230 100644 --- a/src/lj_bcread.c +++ b/src/lj_bcread.c | |||
| @@ -457,7 +457,7 @@ GCproto *lj_bcread(LexState *ls) | |||
| 457 | setprotoV(L, L->top, pt); | 457 | setprotoV(L, L->top, pt); |
| 458 | incr_top(L); | 458 | incr_top(L); |
| 459 | } | 459 | } |
| 460 | if (ls->n != 0 || L->top-1 != bcread_oldtop(L, ls)) | 460 | if ((int32_t)ls->n > 0 || L->top-1 != bcread_oldtop(L, ls)) |
| 461 | bcread_error(ls, LJ_ERR_BCBAD); | 461 | bcread_error(ls, LJ_ERR_BCBAD); |
| 462 | /* Pop off last prototype. */ | 462 | /* Pop off last prototype. */ |
| 463 | L->top--; | 463 | L->top--; |
diff --git a/src/lj_clib.c b/src/lj_clib.c index 7b9b6c1a..ff576d35 100644 --- a/src/lj_clib.c +++ b/src/lj_clib.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | #if defined(RTLD_DEFAULT) | 27 | #if defined(RTLD_DEFAULT) |
| 28 | #define CLIB_DEFHANDLE RTLD_DEFAULT | 28 | #define CLIB_DEFHANDLE RTLD_DEFAULT |
| 29 | #elif LJ_TARGET_OSX || LJ_TARGET_BSD | 29 | #elif LJ_TARGET_OSX || LJ_TARGET_BSD |
| 30 | #define CLIB_DEFHANDLE ((void *)-2) | 30 | #define CLIB_DEFHANDLE ((void *)(intptr_t)-2) |
| 31 | #else | 31 | #else |
| 32 | #define CLIB_DEFHANDLE NULL | 32 | #define CLIB_DEFHANDLE NULL |
| 33 | #endif | 33 | #endif |
