aboutsummaryrefslogtreecommitdiffstats
path: root/deps/LuaJIT/src/lj_clib.c
diff options
context:
space:
mode:
Diffstat (limited to 'deps/LuaJIT/src/lj_clib.c')
-rw-r--r--deps/LuaJIT/src/lj_clib.c430
1 files changed, 0 insertions, 430 deletions
diff --git a/deps/LuaJIT/src/lj_clib.c b/deps/LuaJIT/src/lj_clib.c
deleted file mode 100644
index f016b06..0000000
--- a/deps/LuaJIT/src/lj_clib.c
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
-** FFI C library loader.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
-*/
-
-#include "lj_obj.h"
-
-#if LJ_HASFFI
-
-#include "lj_gc.h"
-#include "lj_err.h"
-#include "lj_tab.h"
-#include "lj_str.h"
-#include "lj_udata.h"
-#include "lj_ctype.h"
-#include "lj_cconv.h"
-#include "lj_cdata.h"
-#include "lj_clib.h"
-#include "lj_strfmt.h"
-
-/* -- OS-specific functions ----------------------------------------------- */
-
-#if LJ_TARGET_DLOPEN
-
-#include <dlfcn.h>
-#include <stdio.h>
-
-#if defined(RTLD_DEFAULT)
-#define CLIB_DEFHANDLE RTLD_DEFAULT
-#elif LJ_TARGET_OSX || LJ_TARGET_BSD
-#define CLIB_DEFHANDLE ((void *)(intptr_t)-2)
-#else
-#define CLIB_DEFHANDLE NULL
-#endif
-
-LJ_NORET LJ_NOINLINE static void clib_error_(lua_State *L)
-{
- lj_err_callermsg(L, dlerror());
-}
-
-#define clib_error(L, fmt, name) clib_error_(L)
-
-#if LJ_TARGET_CYGWIN
-#define CLIB_SOPREFIX "cyg"
-#else
-#define CLIB_SOPREFIX "lib"
-#endif
-
-#if LJ_TARGET_OSX
-#define CLIB_SOEXT "%s.dylib"
-#elif LJ_TARGET_CYGWIN
-#define CLIB_SOEXT "%s.dll"
-#else
-#define CLIB_SOEXT "%s.so"
-#endif
-
-static const char *clib_extname(lua_State *L, const char *name)
-{
- if (!strchr(name, '/')
-#if LJ_TARGET_CYGWIN
- && !strchr(name, '\\')
-#endif
- ) {
- if (!strchr(name, '.')) {
- name = lj_strfmt_pushf(L, CLIB_SOEXT, name);
- L->top--;
-#if LJ_TARGET_CYGWIN
- } else {
- return name;
-#endif
- }
- if (!(name[0] == CLIB_SOPREFIX[0] && name[1] == CLIB_SOPREFIX[1] &&
- name[2] == CLIB_SOPREFIX[2])) {
- name = lj_strfmt_pushf(L, CLIB_SOPREFIX "%s", name);
- L->top--;
- }
- }
- return name;
-}
-
-/* Check for a recognized ld script line. */
-static const char *clib_check_lds(lua_State *L, const char *buf)
-{
- char *p, *e;
- if ((!strncmp(buf, "GROUP", 5) || !strncmp(buf, "INPUT", 5)) &&
- (p = strchr(buf, '('))) {
- while (*++p == ' ') ;
- for (e = p; *e && *e != ' ' && *e != ')'; e++) ;
- return strdata(lj_str_new(L, p, e-p));
- }
- return NULL;
-}
-
-/* Quick and dirty solution to resolve shared library name from ld script. */
-static const char *clib_resolve_lds(lua_State *L, const char *name)
-{
- FILE *fp = fopen(name, "r");
- const char *p = NULL;
- if (fp) {
- char buf[256];
- if (fgets(buf, sizeof(buf), fp)) {
- if (!strncmp(buf, "/* GNU ld script", 16)) { /* ld script magic? */
- while (fgets(buf, sizeof(buf), fp)) { /* Check all lines. */
- p = clib_check_lds(L, buf);
- if (p) break;
- }
- } else { /* Otherwise check only the first line. */
- p = clib_check_lds(L, buf);
- }
- }
- fclose(fp);
- }
- return p;
-}
-
-static void *clib_loadlib(lua_State *L, const char *name, int global)
-{
- void *h = dlopen(clib_extname(L, name),
- RTLD_LAZY | (global?RTLD_GLOBAL:RTLD_LOCAL));
- if (!h) {
- const char *e, *err = dlerror();
- if (*err == '/' && (e = strchr(err, ':')) &&
- (name = clib_resolve_lds(L, strdata(lj_str_new(L, err, e-err))))) {
- h = dlopen(name, RTLD_LAZY | (global?RTLD_GLOBAL:RTLD_LOCAL));
- if (h) return h;
- err = dlerror();
- }
- lj_err_callermsg(L, err);
- }
- return h;
-}
-
-static void clib_unloadlib(CLibrary *cl)
-{
- if (cl->handle && cl->handle != CLIB_DEFHANDLE)
- dlclose(cl->handle);
-}
-
-static void *clib_getsym(CLibrary *cl, const char *name)
-{
- void *p = dlsym(cl->handle, name);
- return p;
-}
-
-#elif LJ_TARGET_WINDOWS
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-#ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
-#define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 4
-#define GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT 2
-BOOL WINAPI GetModuleHandleExA(DWORD, LPCSTR, HMODULE*);
-#endif
-
-#define CLIB_DEFHANDLE ((void *)-1)
-
-/* Default libraries. */
-enum {
- CLIB_HANDLE_EXE,
-#if !LJ_TARGET_UWP
- CLIB_HANDLE_DLL,
- CLIB_HANDLE_CRT,
- CLIB_HANDLE_KERNEL32,
- CLIB_HANDLE_USER32,
- CLIB_HANDLE_GDI32,
-#endif
- CLIB_HANDLE_MAX
-};
-
-static void *clib_def_handle[CLIB_HANDLE_MAX];
-
-LJ_NORET LJ_NOINLINE static void clib_error(lua_State *L, const char *fmt,
- const char *name)
-{
- DWORD err = GetLastError();
-#if LJ_TARGET_XBOXONE
- wchar_t wbuf[128];
- char buf[128*2];
- if (!FormatMessageW(FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, err, 0, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL) ||
- !WideCharToMultiByte(CP_ACP, 0, wbuf, 128, buf, 128*2, NULL, NULL))
-#else
- char buf[128];
- if (!FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, err, 0, buf, sizeof(buf), NULL))
-#endif
- buf[0] = '\0';
- lj_err_callermsg(L, lj_strfmt_pushf(L, fmt, name, buf));
-}
-
-static int clib_needext(const char *s)
-{
- while (*s) {
- if (*s == '/' || *s == '\\' || *s == '.') return 0;
- s++;
- }
- return 1;
-}
-
-static const char *clib_extname(lua_State *L, const char *name)
-{
- if (clib_needext(name)) {
- name = lj_strfmt_pushf(L, "%s.dll", name);
- L->top--;
- }
- return name;
-}
-
-static void *clib_loadlib(lua_State *L, const char *name, int global)
-{
- DWORD oldwerr = GetLastError();
- void *h = LJ_WIN_LOADLIBA(clib_extname(L, name));
- if (!h) clib_error(L, "cannot load module " LUA_QS ": %s", name);
- SetLastError(oldwerr);
- UNUSED(global);
- return h;
-}
-
-static void clib_unloadlib(CLibrary *cl)
-{
- if (cl->handle == CLIB_DEFHANDLE) {
-#if !LJ_TARGET_UWP
- MSize i;
- for (i = CLIB_HANDLE_KERNEL32; i < CLIB_HANDLE_MAX; i++) {
- void *h = clib_def_handle[i];
- if (h) {
- clib_def_handle[i] = NULL;
- FreeLibrary((HINSTANCE)h);
- }
- }
-#endif
- } else if (cl->handle) {
- FreeLibrary((HINSTANCE)cl->handle);
- }
-}
-
-#if LJ_TARGET_UWP
-EXTERN_C IMAGE_DOS_HEADER __ImageBase;
-#endif
-
-static void *clib_getsym(CLibrary *cl, const char *name)
-{
- void *p = NULL;
- if (cl->handle == CLIB_DEFHANDLE) { /* Search default libraries. */
- MSize i;
- for (i = 0; i < CLIB_HANDLE_MAX; i++) {
- HINSTANCE h = (HINSTANCE)clib_def_handle[i];
- if (!(void *)h) { /* Resolve default library handles (once). */
-#if LJ_TARGET_UWP
- h = (HINSTANCE)&__ImageBase;
-#else
- switch (i) {
- case CLIB_HANDLE_EXE: GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, &h); break;
- case CLIB_HANDLE_DLL:
- GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
- (const char *)clib_def_handle, &h);
- break;
- case CLIB_HANDLE_CRT:
- GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
- (const char *)&_fmode, &h);
- break;
- case CLIB_HANDLE_KERNEL32: h = LJ_WIN_LOADLIBA("kernel32.dll"); break;
- case CLIB_HANDLE_USER32: h = LJ_WIN_LOADLIBA("user32.dll"); break;
- case CLIB_HANDLE_GDI32: h = LJ_WIN_LOADLIBA("gdi32.dll"); break;
- }
- if (!h) continue;
-#endif
- clib_def_handle[i] = (void *)h;
- }
- p = (void *)GetProcAddress(h, name);
- if (p) break;
- }
- } else {
- p = (void *)GetProcAddress((HINSTANCE)cl->handle, name);
- }
- return p;
-}
-
-#else
-
-#define CLIB_DEFHANDLE NULL
-
-LJ_NORET LJ_NOINLINE static void clib_error(lua_State *L, const char *fmt,
- const char *name)
-{
- lj_err_callermsg(L, lj_strfmt_pushf(L, fmt, name, "no support for this OS"));
-}
-
-static void *clib_loadlib(lua_State *L, const char *name, int global)
-{
- lj_err_callermsg(L, "no support for loading dynamic libraries for this OS");
- UNUSED(name); UNUSED(global);
- return NULL;
-}
-
-static void clib_unloadlib(CLibrary *cl)
-{
- UNUSED(cl);
-}
-
-static void *clib_getsym(CLibrary *cl, const char *name)
-{
- UNUSED(cl); UNUSED(name);
- return NULL;
-}
-
-#endif
-
-/* -- C library indexing -------------------------------------------------- */
-
-#if LJ_TARGET_X86 && LJ_ABI_WIN
-/* Compute argument size for fastcall/stdcall functions. */
-static CTSize clib_func_argsize(CTState *cts, CType *ct)
-{
- CTSize n = 0;
- while (ct->sib) {
- CType *d;
- ct = ctype_get(cts, ct->sib);
- if (ctype_isfield(ct->info)) {
- d = ctype_rawchild(cts, ct);
- n += ((d->size + 3) & ~3);
- }
- }
- return n;
-}
-#endif
-
-/* Get redirected or mangled external symbol. */
-static const char *clib_extsym(CTState *cts, CType *ct, GCstr *name)
-{
- if (ct->sib) {
- CType *ctf = ctype_get(cts, ct->sib);
- if (ctype_isxattrib(ctf->info, CTA_REDIR))
- return strdata(gco2str(gcref(ctf->name)));
- }
- return strdata(name);
-}
-
-/* Index a C library by name. */
-TValue *lj_clib_index(lua_State *L, CLibrary *cl, GCstr *name)
-{
- TValue *tv = lj_tab_setstr(L, cl->cache, name);
- if (LJ_UNLIKELY(tvisnil(tv))) {
- CTState *cts = ctype_cts(L);
- CType *ct;
- CTypeID id = lj_ctype_getname(cts, &ct, name, CLNS_INDEX);
- if (!id)
- lj_err_callerv(L, LJ_ERR_FFI_NODECL, strdata(name));
- if (ctype_isconstval(ct->info)) {
- CType *ctt = ctype_child(cts, ct);
- lua_assert(ctype_isinteger(ctt->info) && ctt->size <= 4);
- if ((ctt->info & CTF_UNSIGNED) && (int32_t)ct->size < 0)
- setnumV(tv, (lua_Number)(uint32_t)ct->size);
- else
- setintV(tv, (int32_t)ct->size);
- } else {
- const char *sym = clib_extsym(cts, ct, name);
-#if LJ_TARGET_WINDOWS
- DWORD oldwerr = GetLastError();
-#endif
- void *p = clib_getsym(cl, sym);
- GCcdata *cd;
- lua_assert(ctype_isfunc(ct->info) || ctype_isextern(ct->info));
-#if LJ_TARGET_X86 && LJ_ABI_WIN
- /* Retry with decorated name for fastcall/stdcall functions. */
- if (!p && ctype_isfunc(ct->info)) {
- CTInfo cconv = ctype_cconv(ct->info);
- if (cconv == CTCC_FASTCALL || cconv == CTCC_STDCALL) {
- CTSize sz = clib_func_argsize(cts, ct);
- const char *symd = lj_strfmt_pushf(L,
- cconv == CTCC_FASTCALL ? "@%s@%d" : "_%s@%d",
- sym, sz);
- L->top--;
- p = clib_getsym(cl, symd);
- }
- }
-#endif
- if (!p)
- clib_error(L, "cannot resolve symbol " LUA_QS ": %s", sym);
-#if LJ_TARGET_WINDOWS
- SetLastError(oldwerr);
-#endif
- cd = lj_cdata_new(cts, id, CTSIZE_PTR);
- *(void **)cdataptr(cd) = p;
- setcdataV(L, tv, cd);
- }
- }
- return tv;
-}
-
-/* -- C library management ------------------------------------------------ */
-
-/* Create a new CLibrary object and push it on the stack. */
-static CLibrary *clib_new(lua_State *L, GCtab *mt)
-{
- GCtab *t = lj_tab_new(L, 0, 0);
- GCudata *ud = lj_udata_new(L, sizeof(CLibrary), t);
- CLibrary *cl = (CLibrary *)uddata(ud);
- cl->cache = t;
- ud->udtype = UDTYPE_FFI_CLIB;
- /* NOBARRIER: The GCudata is new (marked white). */
- setgcref(ud->metatable, obj2gco(mt));
- setudataV(L, L->top++, ud);
- return cl;
-}
-
-/* Load a C library. */
-void lj_clib_load(lua_State *L, GCtab *mt, GCstr *name, int global)
-{
- void *handle = clib_loadlib(L, strdata(name), global);
- CLibrary *cl = clib_new(L, mt);
- cl->handle = handle;
-}
-
-/* Unload a C library. */
-void lj_clib_unload(CLibrary *cl)
-{
- clib_unloadlib(cl);
- cl->handle = NULL;
-}
-
-/* Create the default C library object. */
-void lj_clib_default(lua_State *L, GCtab *mt)
-{
- CLibrary *cl = clib_new(L, mt);
- cl->handle = CLIB_DEFHANDLE;
-}
-
-#endif