aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/LuaJIT-1.1.7/src/loadlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/LuaJIT-1.1.7/src/loadlib.c')
-rw-r--r--libraries/LuaJIT-1.1.7/src/loadlib.c669
1 files changed, 0 insertions, 669 deletions
diff --git a/libraries/LuaJIT-1.1.7/src/loadlib.c b/libraries/LuaJIT-1.1.7/src/loadlib.c
deleted file mode 100644
index a2da9fc..0000000
--- a/libraries/LuaJIT-1.1.7/src/loadlib.c
+++ /dev/null
@@ -1,669 +0,0 @@
1/*
2** $Id: loadlib.c,v 1.52.1.3 2008/08/06 13:29:28 roberto Exp $
3** Dynamic library loader for Lua
4** See Copyright Notice in lua.h
5**
6** This module contains an implementation of loadlib for Unix systems
7** that have dlfcn, an implementation for Darwin (Mac OS X), an
8** implementation for Windows, and a stub for other systems.
9*/
10
11
12#include <stdlib.h>
13#include <string.h>
14
15
16#define loadlib_c
17#define LUA_LIB
18
19#include "lua.h"
20
21#include "lauxlib.h"
22#include "lualib.h"
23#include "luajit.h"
24
25
26/* prefix for open functions in C libraries */
27#define LUA_POF "luaopen_"
28
29/* separator for open functions in C libraries */
30#define LUA_OFSEP "_"
31
32
33#define LIBPREFIX "LOADLIB: "
34
35#define POF LUA_POF
36#define LIB_FAIL "open"
37
38
39/* error codes for ll_loadfunc */
40#define ERRLIB 1
41#define ERRFUNC 2
42
43#define setprogdir(L) ((void)0)
44
45
46static void ll_unloadlib (void *lib);
47static void *ll_load (lua_State *L, const char *path);
48static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
49
50
51
52#if defined(LUA_DL_DLOPEN)
53/*
54** {========================================================================
55** This is an implementation of loadlib based on the dlfcn interface.
56** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
57** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
58** as an emulation layer on top of native functions.
59** =========================================================================
60*/
61
62#include <dlfcn.h>
63
64static void ll_unloadlib (void *lib) {
65 dlclose(lib);
66}
67
68
69static void *ll_load (lua_State *L, const char *path) {
70 void *lib = dlopen(path, RTLD_NOW);
71 if (lib == NULL) lua_pushstring(L, dlerror());
72 return lib;
73}
74
75
76static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
77 lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
78 if (f == NULL) lua_pushstring(L, dlerror());
79 return f;
80}
81
82/* }====================================================== */
83
84
85
86#elif defined(LUA_DL_DLL)
87/*
88** {======================================================================
89** This is an implementation of loadlib for Windows using native functions.
90** =======================================================================
91*/
92
93#include <windows.h>
94
95
96#undef setprogdir
97
98static void setprogdir (lua_State *L) {
99 char buff[MAX_PATH + 1];
100 char *lb;
101 DWORD nsize = sizeof(buff)/sizeof(char);
102 DWORD n = GetModuleFileNameA(NULL, buff, nsize);
103 if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
104 luaL_error(L, "unable to get ModuleFileName");
105 else {
106 *lb = '\0';
107 luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff);
108 lua_remove(L, -2); /* remove original string */
109 }
110}
111
112
113static void pusherror (lua_State *L) {
114 int error = GetLastError();
115 char buffer[128];
116 if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
117 NULL, error, 0, buffer, sizeof(buffer), NULL))
118 lua_pushstring(L, buffer);
119 else
120 lua_pushfstring(L, "system error %d\n", error);
121}
122
123static void ll_unloadlib (void *lib) {
124 FreeLibrary((HINSTANCE)lib);
125}
126
127
128static void *ll_load (lua_State *L, const char *path) {
129 HINSTANCE lib = LoadLibraryA(path);
130 if (lib == NULL) pusherror(L);
131 return lib;
132}
133
134
135static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
136 lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym);
137 if (f == NULL) pusherror(L);
138 return f;
139}
140
141/* }====================================================== */
142
143
144
145#elif defined(LUA_DL_DYLD)
146/*
147** {======================================================================
148** Native Mac OS X / Darwin Implementation
149** =======================================================================
150*/
151
152#include <mach-o/dyld.h>
153
154
155/* Mac appends a `_' before C function names */
156#undef POF
157#define POF "_" LUA_POF
158
159
160static void pusherror (lua_State *L) {
161 const char *err_str;
162 const char *err_file;
163 NSLinkEditErrors err;
164 int err_num;
165 NSLinkEditError(&err, &err_num, &err_file, &err_str);
166 lua_pushstring(L, err_str);
167}
168
169
170static const char *errorfromcode (NSObjectFileImageReturnCode ret) {
171 switch (ret) {
172 case NSObjectFileImageInappropriateFile:
173 return "file is not a bundle";
174 case NSObjectFileImageArch:
175 return "library is for wrong CPU type";
176 case NSObjectFileImageFormat:
177 return "bad format";
178 case NSObjectFileImageAccess:
179 return "cannot access file";
180 case NSObjectFileImageFailure:
181 default:
182 return "unable to load library";
183 }
184}
185
186
187static void ll_unloadlib (void *lib) {
188 NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES);
189}
190
191
192static void *ll_load (lua_State *L, const char *path) {
193 NSObjectFileImage img;
194 NSObjectFileImageReturnCode ret;
195 /* this would be a rare case, but prevents crashing if it happens */
196 if(!_dyld_present()) {
197 lua_pushliteral(L, "dyld not present");
198 return NULL;
199 }
200 ret = NSCreateObjectFileImageFromFile(path, &img);
201 if (ret == NSObjectFileImageSuccess) {
202 NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE |
203 NSLINKMODULE_OPTION_RETURN_ON_ERROR);
204 NSDestroyObjectFileImage(img);
205 if (mod == NULL) pusherror(L);
206 return mod;
207 }
208 lua_pushstring(L, errorfromcode(ret));
209 return NULL;
210}
211
212
213static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
214 NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym);
215 if (nss == NULL) {
216 lua_pushfstring(L, "symbol " LUA_QS " not found", sym);
217 return NULL;
218 }
219 return (lua_CFunction)NSAddressOfSymbol(nss);
220}
221
222/* }====================================================== */
223
224
225
226#else
227/*
228** {======================================================
229** Fallback for other systems
230** =======================================================
231*/
232
233#undef LIB_FAIL
234#define LIB_FAIL "absent"
235
236
237#define DLMSG "dynamic libraries not enabled; check your Lua installation"
238
239
240static void ll_unloadlib (void *lib) {
241 (void)lib; /* to avoid warnings */
242}
243
244
245static void *ll_load (lua_State *L, const char *path) {
246 (void)path; /* to avoid warnings */
247 lua_pushliteral(L, DLMSG);
248 return NULL;
249}
250
251
252static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
253 (void)lib; (void)sym; /* to avoid warnings */
254 lua_pushliteral(L, DLMSG);
255 return NULL;
256}
257
258/* }====================================================== */
259#endif
260
261
262
263static void **ll_register (lua_State *L, const char *path) {
264 void **plib;
265 lua_pushfstring(L, "%s%s", LIBPREFIX, path);
266 lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */
267 if (!lua_isnil(L, -1)) /* is there an entry? */
268 plib = (void **)lua_touserdata(L, -1);
269 else { /* no entry yet; create one */
270 lua_pop(L, 1);
271 plib = (void **)lua_newuserdata(L, sizeof(const void *));
272 *plib = NULL;
273 luaL_getmetatable(L, "_LOADLIB");
274 lua_setmetatable(L, -2);
275 lua_pushfstring(L, "%s%s", LIBPREFIX, path);
276 lua_pushvalue(L, -2);
277 lua_settable(L, LUA_REGISTRYINDEX);
278 }
279 return plib;
280}
281
282
283/*
284** __gc tag method: calls library's `ll_unloadlib' function with the lib
285** handle
286*/
287static int gctm (lua_State *L) {
288 void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB");
289 if (*lib) ll_unloadlib(*lib);
290 *lib = NULL; /* mark library as closed */
291 return 0;
292}
293
294
295static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
296 void **reg = ll_register(L, path);
297 if (*reg == NULL) *reg = ll_load(L, path);
298 if (*reg == NULL)
299 return ERRLIB; /* unable to load library */
300 else {
301 lua_CFunction f = ll_sym(L, *reg, sym);
302 if (f == NULL)
303 return ERRFUNC; /* unable to find function */
304 lua_pushcfunction(L, f);
305 return 0; /* return function */
306 }
307}
308
309
310static int ll_loadlib (lua_State *L) {
311 const char *path = luaL_checkstring(L, 1);
312 const char *init = luaL_checkstring(L, 2);
313 int stat = ll_loadfunc(L, path, init);
314 if (stat == 0) /* no errors? */
315 return 1; /* return the loaded function */
316 else { /* error; error message is on stack top */
317 lua_pushnil(L);
318 lua_insert(L, -2);
319 lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
320 return 3; /* return nil, error message, and where */
321 }
322}
323
324
325
326/*
327** {======================================================
328** 'require' function
329** =======================================================
330*/
331
332
333static int readable (const char *filename) {
334 FILE *f = fopen(filename, "r"); /* try to open file */
335 if (f == NULL) return 0; /* open failed */
336 fclose(f);
337 return 1;
338}
339
340
341static const char *pushnexttemplate (lua_State *L, const char *path) {
342 const char *l;
343 while (*path == *LUA_PATHSEP) path++; /* skip separators */
344 if (*path == '\0') return NULL; /* no more templates */
345 l = strchr(path, *LUA_PATHSEP); /* find next separator */
346 if (l == NULL) l = path + strlen(path);
347 lua_pushlstring(L, path, l - path); /* template */
348 return l;
349}
350
351
352static const char *findfile (lua_State *L, const char *name,
353 const char *pname) {
354 const char *path;
355 name = luaL_gsub(L, name, ".", LUA_DIRSEP);
356 lua_getfield(L, LUA_ENVIRONINDEX, pname);
357 path = lua_tostring(L, -1);
358 if (path == NULL)
359 luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
360 lua_pushliteral(L, ""); /* error accumulator */
361 while ((path = pushnexttemplate(L, path)) != NULL) {
362 const char *filename;
363 filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name);
364 lua_remove(L, -2); /* remove path template */
365 if (readable(filename)) /* does file exist and is readable? */
366 return filename; /* return that file name */
367 lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
368 lua_remove(L, -2); /* remove file name */
369 lua_concat(L, 2); /* add entry to possible error message */
370 }
371 return NULL; /* not found */
372}
373
374
375static void loaderror (lua_State *L, const char *filename) {
376 luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s",
377 lua_tostring(L, 1), filename, lua_tostring(L, -1));
378}
379
380
381static int loader_Lua (lua_State *L) {
382 const char *filename;
383 const char *name = luaL_checkstring(L, 1);
384 filename = findfile(L, name, "path");
385 if (filename == NULL) return 1; /* library not found in this path */
386 if (luaL_loadfile(L, filename) != 0)
387 loaderror(L, filename);
388 /* not useful to JIT compile main chunk of a module */
389 luaJIT_setmode(L, -1, LUAJIT_MODE_FUNC|LUAJIT_MODE_OFF);
390 return 1; /* library loaded successfully */
391}
392
393
394static const char *mkfuncname (lua_State *L, const char *modname) {
395 const char *funcname;
396 const char *mark = strchr(modname, *LUA_IGMARK);
397 if (mark) modname = mark + 1;
398 funcname = luaL_gsub(L, modname, ".", LUA_OFSEP);
399 funcname = lua_pushfstring(L, POF"%s", funcname);
400 lua_remove(L, -2); /* remove 'gsub' result */
401 return funcname;
402}
403
404
405static int loader_C (lua_State *L) {
406 const char *funcname;
407 const char *name = luaL_checkstring(L, 1);
408 const char *filename = findfile(L, name, "cpath");
409 if (filename == NULL) return 1; /* library not found in this path */
410 funcname = mkfuncname(L, name);
411 if (ll_loadfunc(L, filename, funcname) != 0)
412 loaderror(L, filename);
413 return 1; /* library loaded successfully */
414}
415
416
417static int loader_Croot (lua_State *L) {
418 const char *funcname;
419 const char *filename;
420 const char *name = luaL_checkstring(L, 1);
421 const char *p = strchr(name, '.');
422 int stat;
423 if (p == NULL) return 0; /* is root */
424 lua_pushlstring(L, name, p - name);
425 filename = findfile(L, lua_tostring(L, -1), "cpath");
426 if (filename == NULL) return 1; /* root not found */
427 funcname = mkfuncname(L, name);
428 if ((stat = ll_loadfunc(L, filename, funcname)) != 0) {
429 if (stat != ERRFUNC) loaderror(L, filename); /* real error */
430 lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
431 name, filename);
432 return 1; /* function not found */
433 }
434 return 1;
435}
436
437
438static int loader_preload (lua_State *L) {
439 const char *name = luaL_checkstring(L, 1);
440 lua_getfield(L, LUA_ENVIRONINDEX, "preload");
441 if (!lua_istable(L, -1))
442 luaL_error(L, LUA_QL("package.preload") " must be a table");
443 lua_getfield(L, -1, name);
444 if (lua_isnil(L, -1)) /* not found? */
445 lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
446 return 1;
447}
448
449
450static const int sentinel_ = 0;
451#define sentinel ((void *)&sentinel_)
452
453
454static int ll_require (lua_State *L) {
455 const char *name = luaL_checkstring(L, 1);
456 int i;
457 lua_settop(L, 1); /* _LOADED table will be at index 2 */
458 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
459 lua_getfield(L, 2, name);
460 if (lua_toboolean(L, -1)) { /* is it there? */
461 if (lua_touserdata(L, -1) == sentinel) /* check loops */
462 luaL_error(L, "loop or previous error loading module " LUA_QS, name);
463 return 1; /* package is already loaded */
464 }
465 /* else must load it; iterate over available loaders */
466 lua_getfield(L, LUA_ENVIRONINDEX, "loaders");
467 if (!lua_istable(L, -1))
468 luaL_error(L, LUA_QL("package.loaders") " must be a table");
469 lua_pushliteral(L, ""); /* error message accumulator */
470 for (i=1; ; i++) {
471 lua_rawgeti(L, -2, i); /* get a loader */
472 if (lua_isnil(L, -1))
473 luaL_error(L, "module " LUA_QS " not found:%s",
474 name, lua_tostring(L, -2));
475 lua_pushstring(L, name);
476 lua_call(L, 1, 1); /* call it */
477 if (lua_isfunction(L, -1)) /* did it find module? */
478 break; /* module loaded successfully */
479 else if (lua_isstring(L, -1)) /* loader returned error message? */
480 lua_concat(L, 2); /* accumulate it */
481 else
482 lua_pop(L, 1);
483 }
484 lua_pushlightuserdata(L, sentinel);
485 lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */
486 lua_pushstring(L, name); /* pass name as argument to module */
487 lua_call(L, 1, 1); /* run loaded module */
488 if (!lua_isnil(L, -1)) /* non-nil return? */
489 lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
490 lua_getfield(L, 2, name);
491 if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */
492 lua_pushboolean(L, 1); /* use true as result */
493 lua_pushvalue(L, -1); /* extra copy to be returned */
494 lua_setfield(L, 2, name); /* _LOADED[name] = true */
495 }
496 return 1;
497}
498
499/* }====================================================== */
500
501
502
503/*
504** {======================================================
505** 'module' function
506** =======================================================
507*/
508
509
510static void setfenv (lua_State *L) {
511 lua_Debug ar;
512 if (lua_getstack(L, 1, &ar) == 0 ||
513 lua_getinfo(L, "f", &ar) == 0 || /* get calling function */
514 lua_iscfunction(L, -1))
515 luaL_error(L, LUA_QL("module") " not called from a Lua function");
516 lua_pushvalue(L, -2);
517 lua_setfenv(L, -2);
518 lua_pop(L, 1);
519}
520
521
522static void dooptions (lua_State *L, int n) {
523 int i;
524 for (i = 2; i <= n; i++) {
525 lua_pushvalue(L, i); /* get option (a function) */
526 lua_pushvalue(L, -2); /* module */
527 lua_call(L, 1, 0);
528 }
529}
530
531
532static void modinit (lua_State *L, const char *modname) {
533 const char *dot;
534 lua_pushvalue(L, -1);
535 lua_setfield(L, -2, "_M"); /* module._M = module */
536 lua_pushstring(L, modname);
537 lua_setfield(L, -2, "_NAME");
538 dot = strrchr(modname, '.'); /* look for last dot in module name */
539 if (dot == NULL) dot = modname;
540 else dot++;
541 /* set _PACKAGE as package name (full module name minus last part) */
542 lua_pushlstring(L, modname, dot - modname);
543 lua_setfield(L, -2, "_PACKAGE");
544}
545
546
547static int ll_module (lua_State *L) {
548 const char *modname = luaL_checkstring(L, 1);
549 int loaded = lua_gettop(L) + 1; /* index of _LOADED table */
550 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
551 lua_getfield(L, loaded, modname); /* get _LOADED[modname] */
552 if (!lua_istable(L, -1)) { /* not found? */
553 lua_pop(L, 1); /* remove previous result */
554 /* try global variable (and create one if it does not exist) */
555 if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL)
556 return luaL_error(L, "name conflict for module " LUA_QS, modname);
557 lua_pushvalue(L, -1);
558 lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */
559 }
560 /* check whether table already has a _NAME field */
561 lua_getfield(L, -1, "_NAME");
562 if (!lua_isnil(L, -1)) /* is table an initialized module? */
563 lua_pop(L, 1);
564 else { /* no; initialize it */
565 lua_pop(L, 1);
566 modinit(L, modname);
567 }
568 lua_pushvalue(L, -1);
569 setfenv(L);
570 dooptions(L, loaded - 1);
571 return 0;
572}
573
574
575static int ll_seeall (lua_State *L) {
576 luaL_checktype(L, 1, LUA_TTABLE);
577 if (!lua_getmetatable(L, 1)) {
578 lua_createtable(L, 0, 1); /* create new metatable */
579 lua_pushvalue(L, -1);
580 lua_setmetatable(L, 1);
581 }
582 lua_pushvalue(L, LUA_GLOBALSINDEX);
583 lua_setfield(L, -2, "__index"); /* mt.__index = _G */
584 return 0;
585}
586
587
588/* }====================================================== */
589
590
591
592/* auxiliary mark (for internal use) */
593#define AUXMARK "\1"
594
595static void setpath (lua_State *L, const char *fieldname, const char *envname,
596 const char *def) {
597 const char *path = getenv(envname);
598 if (path == NULL) /* no environment variable? */
599 lua_pushstring(L, def); /* use default */
600 else {
601 /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
602 path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP,
603 LUA_PATHSEP AUXMARK LUA_PATHSEP);
604 luaL_gsub(L, path, AUXMARK, def);
605 lua_remove(L, -2);
606 }
607 setprogdir(L);
608 lua_setfield(L, -2, fieldname);
609}
610
611
612static const luaL_Reg pk_funcs[] = {
613 {"loadlib", ll_loadlib},
614 {"seeall", ll_seeall},
615 {NULL, NULL}
616};
617
618
619static const luaL_Reg ll_funcs[] = {
620 {"module", ll_module},
621 {"require", ll_require},
622 {NULL, NULL}
623};
624
625
626static const lua_CFunction loaders[] =
627 {loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
628
629
630LUALIB_API int luaopen_package (lua_State *L) {
631 int i;
632 /* create new type _LOADLIB */
633 luaL_newmetatable(L, "_LOADLIB");
634 lua_pushcfunction(L, gctm);
635 lua_setfield(L, -2, "__gc");
636 /* create `package' table */
637 luaL_register(L, LUA_LOADLIBNAME, pk_funcs);
638#if defined(LUA_COMPAT_LOADLIB)
639 lua_getfield(L, -1, "loadlib");
640 lua_setfield(L, LUA_GLOBALSINDEX, "loadlib");
641#endif
642 lua_pushvalue(L, -1);
643 lua_replace(L, LUA_ENVIRONINDEX);
644 /* create `loaders' table */
645 lua_createtable(L, sizeof(loaders)/sizeof(loaders[0]) - 1, 0);
646 /* fill it with pre-defined loaders */
647 for (i=0; loaders[i] != NULL; i++) {
648 lua_pushcfunction(L, loaders[i]);
649 lua_rawseti(L, -2, i+1);
650 }
651 lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */
652 setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */
653 setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */
654 /* store config information */
655 lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n"
656 LUA_EXECDIR "\n" LUA_IGMARK);
657 lua_setfield(L, -2, "config");
658 /* set field `loaded' */
659 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2);
660 lua_setfield(L, -2, "loaded");
661 /* set field `preload' */
662 lua_newtable(L);
663 lua_setfield(L, -2, "preload");
664 lua_pushvalue(L, LUA_GLOBALSINDEX);
665 luaL_register(L, NULL, ll_funcs); /* open lib into global table */
666 lua_pop(L, 1);
667 return 1; /* return 'package' table */
668}
669