|
@@ -31,38 +31,39 @@
|
|
#define CLIB_DEFHANDLE NULL
|
|
#define CLIB_DEFHANDLE NULL
|
|
#endif
|
|
#endif
|
|
|
|
|
|
-LJ_NORET LJ_NOINLINE static void clib_error(lua_State *L)
|
|
|
|
|
|
+LJ_NORET LJ_NOINLINE static void clib_error_(lua_State *L)
|
|
{
|
|
{
|
|
lj_err_callermsg(L, dlerror());
|
|
lj_err_callermsg(L, dlerror());
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#define clib_error(L, fmt, name) clib_error_(L)
|
|
|
|
+
|
|
#if LJ_TARGET_OSX
|
|
#if LJ_TARGET_OSX
|
|
#define CLIB_SOEXT "%s.dylib"
|
|
#define CLIB_SOEXT "%s.dylib"
|
|
#else
|
|
#else
|
|
#define CLIB_SOEXT "%s.so"
|
|
#define CLIB_SOEXT "%s.so"
|
|
#endif
|
|
#endif
|
|
|
|
|
|
-static const char *clib_extname(lua_State *L, GCstr *name)
|
|
|
|
|
|
+static const char *clib_extname(lua_State *L, const char *name)
|
|
{
|
|
{
|
|
- const char *s = strdata(name);
|
|
|
|
- if (!strchr(s, '/')) {
|
|
|
|
- if (!strchr(s, '.')) {
|
|
|
|
- s = lj_str_pushf(L, CLIB_SOEXT, s);
|
|
|
|
|
|
+ if (!strchr(name, '/')) {
|
|
|
|
+ if (!strchr(name, '.')) {
|
|
|
|
+ name = lj_str_pushf(L, CLIB_SOEXT, name);
|
|
L->top--;
|
|
L->top--;
|
|
}
|
|
}
|
|
- if (!(s[0] == 'l' && s[1] == 'i' && s[2] == 'b')) {
|
|
|
|
- s = lj_str_pushf(L, "lib%s", s);
|
|
|
|
|
|
+ if (!(name[0] == 'l' && name[1] == 'i' && name[2] == 'b')) {
|
|
|
|
+ name = lj_str_pushf(L, "lib%s", name);
|
|
L->top--;
|
|
L->top--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- return s;
|
|
|
|
|
|
+ return name;
|
|
}
|
|
}
|
|
|
|
|
|
-static void *clib_loadlib(lua_State *L, GCstr *name, int global)
|
|
|
|
|
|
+static void *clib_loadlib(lua_State *L, const char *name, int global)
|
|
{
|
|
{
|
|
void *h = dlopen(clib_extname(L, name),
|
|
void *h = dlopen(clib_extname(L, name),
|
|
RTLD_LAZY | (global?RTLD_GLOBAL:RTLD_LOCAL));
|
|
RTLD_LAZY | (global?RTLD_GLOBAL:RTLD_LOCAL));
|
|
- if (!h) clib_error(L);
|
|
|
|
|
|
+ if (!h) clib_error_(L);
|
|
return h;
|
|
return h;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -72,10 +73,9 @@ static void clib_unloadlib(CLibrary *cl)
|
|
dlclose(cl->handle);
|
|
dlclose(cl->handle);
|
|
}
|
|
}
|
|
|
|
|
|
-static void *clib_getsym(lua_State *L, CLibrary *cl, GCstr *name)
|
|
|
|
|
|
+static void *clib_getsym(CLibrary *cl, const char *name)
|
|
{
|
|
{
|
|
- void *p = dlsym(cl->handle, strdata(name));
|
|
|
|
- if (!p) clib_error(L);
|
|
|
|
|
|
+ void *p = dlsym(cl->handle, name);
|
|
return p;
|
|
return p;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -127,17 +127,16 @@ static int clib_needext(const char *s)
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
-static const char *clib_extname(lua_State *L, GCstr *name)
|
|
|
|
|
|
+static const char *clib_extname(lua_State *L, const char *name)
|
|
{
|
|
{
|
|
- const char *s = strdata(name);
|
|
|
|
- if (clib_needext(s)) {
|
|
|
|
- s = lj_str_pushf(L, "%s.dll", s);
|
|
|
|
|
|
+ if (clib_needext(name)) {
|
|
|
|
+ name = lj_str_pushf(L, "%s.dll", name);
|
|
L->top--;
|
|
L->top--;
|
|
}
|
|
}
|
|
- return s;
|
|
|
|
|
|
+ return name;
|
|
}
|
|
}
|
|
|
|
|
|
-static void *clib_loadlib(lua_State *L, GCstr *name, int global)
|
|
|
|
|
|
+static void *clib_loadlib(lua_State *L, const char *name, int global)
|
|
{
|
|
{
|
|
void *h = (void *)LoadLibraryA(clib_extname(L, name));
|
|
void *h = (void *)LoadLibraryA(clib_extname(L, name));
|
|
if (!h) clib_error(L, "cannot load module " LUA_QS ": %s", strdata(name));
|
|
if (!h) clib_error(L, "cannot load module " LUA_QS ": %s", strdata(name));
|
|
@@ -157,9 +156,8 @@ static void clib_unloadlib(CLibrary *cl)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-static void *clib_getsym(lua_State *L, CLibrary *cl, GCstr *name)
|
|
|
|
|
|
+static void *clib_getsym(CLibrary *cl, const char *name)
|
|
{
|
|
{
|
|
- const char *sym = strdata(name);
|
|
|
|
void *p;
|
|
void *p;
|
|
if (cl->handle == CLIB_DEFHANDLE) { /* Search default libraries. */
|
|
if (cl->handle == CLIB_DEFHANDLE) { /* Search default libraries. */
|
|
MSize i;
|
|
MSize i;
|
|
@@ -183,13 +181,12 @@ static void *clib_getsym(lua_State *L, CLibrary *cl, GCstr *name)
|
|
if (!h) continue;
|
|
if (!h) continue;
|
|
clib_def_handle[i] = (void *)h;
|
|
clib_def_handle[i] = (void *)h;
|
|
}
|
|
}
|
|
- p = (void *)GetProcAddress(h, sym);
|
|
|
|
|
|
+ p = (void *)GetProcAddress(h, name);
|
|
if (p) break;
|
|
if (p) break;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- p = (void *)GetProcAddress((HINSTANCE)cl->handle, sym);
|
|
|
|
|
|
+ p = (void *)GetProcAddress((HINSTANCE)cl->handle, name);
|
|
}
|
|
}
|
|
- if (!p) clib_error(L, "cannot resolve symbol " LUA_QS ": %s", sym);
|
|
|
|
return p;
|
|
return p;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -197,7 +194,13 @@ static void *clib_getsym(lua_State *L, CLibrary *cl, GCstr *name)
|
|
|
|
|
|
#define CLIB_DEFHANDLE NULL
|
|
#define CLIB_DEFHANDLE NULL
|
|
|
|
|
|
-static void *clib_loadlib(lua_State *L, GCstr *name, int global)
|
|
|
|
|
|
+LJ_NORET LJ_NOINLINE static void clib_error(lua_State *L, const char *fmt,
|
|
|
|
+ const char *name)
|
|
|
|
+{
|
|
|
|
+ lj_err_callermsg(L, lj_str_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");
|
|
lj_err_callermsg(L, "no support for loading dynamic libraries for this OS");
|
|
UNUSED(name); UNUSED(global);
|
|
UNUSED(name); UNUSED(global);
|
|
@@ -209,9 +212,8 @@ static void clib_unloadlib(CLibrary *cl)
|
|
UNUSED(cl);
|
|
UNUSED(cl);
|
|
}
|
|
}
|
|
|
|
|
|
-static void *clib_getsym(lua_State *L, CLibrary *cl, GCstr *name)
|
|
|
|
|
|
+static void *clib_getsym(CLibrary *cl, const char *name)
|
|
{
|
|
{
|
|
- lj_err_callermsg(L, "no support for resolving symbols for this OS");
|
|
|
|
UNUSED(cl); UNUSED(name);
|
|
UNUSED(cl); UNUSED(name);
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
@@ -224,6 +226,22 @@ static void *clib_getsym(lua_State *L, CLibrary *cl, GCstr *name)
|
|
#define CLNS_INDEX \
|
|
#define CLNS_INDEX \
|
|
((1u<<CT_FUNC)|(1u<<CT_EXTERN)|(1u<<CT_CONSTVAL))
|
|
((1u<<CT_FUNC)|(1u<<CT_EXTERN)|(1u<<CT_CONSTVAL))
|
|
|
|
|
|
|
|
+#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);
|
|
|
|
+ lua_assert(ctype_isfield(ct->info));
|
|
|
|
+ d = ctype_rawchild(cts, ct);
|
|
|
|
+ n += ((d->size + 3) & ~3);
|
|
|
|
+ }
|
|
|
|
+ return n;
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
/* Index a C library by name. */
|
|
/* Index a C library by name. */
|
|
TValue *lj_clib_index(lua_State *L, CLibrary *cl, GCstr *name)
|
|
TValue *lj_clib_index(lua_State *L, CLibrary *cl, GCstr *name)
|
|
{
|
|
{
|
|
@@ -242,9 +260,24 @@ TValue *lj_clib_index(lua_State *L, CLibrary *cl, GCstr *name)
|
|
else
|
|
else
|
|
setnumV(tv, (lua_Number)(int32_t)ct->size);
|
|
setnumV(tv, (lua_Number)(int32_t)ct->size);
|
|
} else {
|
|
} else {
|
|
- void *p = clib_getsym(L, cl, name);
|
|
|
|
|
|
+ void *p = clib_getsym(cl, strdata(name));
|
|
GCcdata *cd;
|
|
GCcdata *cd;
|
|
lua_assert(ctype_isfunc(ct->info) || ctype_isextern(ct->info));
|
|
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 *sym = lj_str_pushf(L,
|
|
|
|
+ cconv == CTCC_FASTCALL ? "@%s@%d" : "_%s@%d", strdata(name), sz);
|
|
|
|
+ L->top--;
|
|
|
|
+ p = clib_getsym(cl, sym);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+ if (!p)
|
|
|
|
+ clib_error(L, "cannot resolve symbol " LUA_QS ": %s", strdata(name));
|
|
cd = lj_cdata_new(cts, id, CTSIZE_PTR);
|
|
cd = lj_cdata_new(cts, id, CTSIZE_PTR);
|
|
*(void **)cdataptr(cd) = p;
|
|
*(void **)cdataptr(cd) = p;
|
|
setcdataV(L, tv, cd);
|
|
setcdataV(L, tv, cd);
|
|
@@ -272,7 +305,7 @@ static CLibrary *clib_new(lua_State *L, GCtab *mt)
|
|
/* Load a C library. */
|
|
/* Load a C library. */
|
|
void lj_clib_load(lua_State *L, GCtab *mt, GCstr *name, int global)
|
|
void lj_clib_load(lua_State *L, GCtab *mt, GCstr *name, int global)
|
|
{
|
|
{
|
|
- void *handle = clib_loadlib(L, name, global);
|
|
|
|
|
|
+ void *handle = clib_loadlib(L, strdata(name), global);
|
|
CLibrary *cl = clib_new(L, mt);
|
|
CLibrary *cl = clib_new(L, mt);
|
|
cl->handle = handle;
|
|
cl->handle = handle;
|
|
}
|
|
}
|