mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
FFI: Add symbol name redirection.
This works like the GCC extension, e.g.: FILE *fopen(const char *fn, const char *mode) __asm__("" "fopen64");
This commit is contained in:
parent
ed6c895ae5
commit
1b75ec22c8
@ -275,8 +275,16 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Skip initial attributes. */
|
||||||
|
fid = ct->sib;
|
||||||
|
while (fid) {
|
||||||
|
CType *ctf = ctype_get(cts, fid);
|
||||||
|
if (!ctype_isattrib(ctf->info)) break;
|
||||||
|
fid = ctf->sib;
|
||||||
|
}
|
||||||
|
|
||||||
/* Walk through all passed arguments. */
|
/* Walk through all passed arguments. */
|
||||||
for (fid = ct->sib, o = L->base+1; o < top; o++) {
|
for (o = L->base+1; o < top; o++) {
|
||||||
CTypeID did;
|
CTypeID did;
|
||||||
CType *d;
|
CType *d;
|
||||||
CTSize sz;
|
CTSize sz;
|
||||||
|
@ -242,6 +242,17 @@ static CTSize clib_func_argsize(CTState *cts, CType *ct)
|
|||||||
}
|
}
|
||||||
#endif
|
#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. */
|
/* 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)
|
||||||
{
|
{
|
||||||
@ -260,7 +271,8 @@ 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(cl, strdata(name));
|
const char *sym = clib_extsym(cts, ct, name);
|
||||||
|
void *p = clib_getsym(cl, sym);
|
||||||
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
|
#if LJ_TARGET_X86 && LJ_ABI_WIN
|
||||||
@ -269,8 +281,8 @@ TValue *lj_clib_index(lua_State *L, CLibrary *cl, GCstr *name)
|
|||||||
CTInfo cconv = ctype_cconv(ct->info);
|
CTInfo cconv = ctype_cconv(ct->info);
|
||||||
if (cconv == CTCC_FASTCALL || cconv == CTCC_STDCALL) {
|
if (cconv == CTCC_FASTCALL || cconv == CTCC_STDCALL) {
|
||||||
CTSize sz = clib_func_argsize(cts, ct);
|
CTSize sz = clib_func_argsize(cts, ct);
|
||||||
const char *sym = lj_str_pushf(L,
|
sym = lj_str_pushf(L, cconv == CTCC_FASTCALL ? "@%s@%d" : "_%s@%d",
|
||||||
cconv == CTCC_FASTCALL ? "@%s@%d" : "_%s@%d", strdata(name), sz);
|
sym, sz);
|
||||||
L->top--;
|
L->top--;
|
||||||
p = clib_getsym(cl, sym);
|
p = clib_getsym(cl, sym);
|
||||||
}
|
}
|
||||||
|
@ -342,6 +342,7 @@ typedef struct CPDecl {
|
|||||||
uint32_t mode; /* Declarator mode. */
|
uint32_t mode; /* Declarator mode. */
|
||||||
CPState *cp; /* C parser state. */
|
CPState *cp; /* C parser state. */
|
||||||
GCstr *name; /* Name of declared identifier (if direct). */
|
GCstr *name; /* Name of declared identifier (if direct). */
|
||||||
|
GCstr *redir; /* Redirected symbol name. */
|
||||||
CTypeID nameid; /* Existing typedef for declared identifier. */
|
CTypeID nameid; /* Existing typedef for declared identifier. */
|
||||||
CTInfo attr; /* Attributes. */
|
CTInfo attr; /* Attributes. */
|
||||||
CTInfo fattr; /* Function attributes. */
|
CTInfo fattr; /* Function attributes. */
|
||||||
@ -923,6 +924,7 @@ static void cp_decl_reset(CPDecl *decl)
|
|||||||
decl->attr = decl->specattr;
|
decl->attr = decl->specattr;
|
||||||
decl->fattr = decl->specfattr;
|
decl->fattr = decl->specfattr;
|
||||||
decl->name = NULL;
|
decl->name = NULL;
|
||||||
|
decl->redir = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse constant initializer. */
|
/* Parse constant initializer. */
|
||||||
@ -982,7 +984,15 @@ static void cp_decl_asm(CPState *cp, CPDecl *decl)
|
|||||||
UNUSED(decl);
|
UNUSED(decl);
|
||||||
cp_next(cp);
|
cp_next(cp);
|
||||||
cp_check(cp, '(');
|
cp_check(cp, '(');
|
||||||
while (cp->tok == CTOK_STRING) cp_next(cp); /* NYI: currently ignored. */
|
if (cp->tok == CTOK_STRING) {
|
||||||
|
GCstr *str = cp->str;
|
||||||
|
while (cp_next(cp) == CTOK_STRING) {
|
||||||
|
lj_str_pushf(cp->L, "%s%s", strdata(str), strdata(cp->str));
|
||||||
|
cp->L->top--;
|
||||||
|
str = strV(cp->L->top);
|
||||||
|
}
|
||||||
|
decl->redir = str;
|
||||||
|
}
|
||||||
cp_check(cp, ')');
|
cp_check(cp, ')');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1428,6 +1438,7 @@ static CPscl cp_decl_spec(CPState *cp, CPDecl *decl, CPscl scl)
|
|||||||
decl->cp = cp;
|
decl->cp = cp;
|
||||||
decl->mode = cp->mode;
|
decl->mode = cp->mode;
|
||||||
decl->name = NULL;
|
decl->name = NULL;
|
||||||
|
decl->redir = NULL;
|
||||||
decl->attr = 0;
|
decl->attr = 0;
|
||||||
decl->fattr = 0;
|
decl->fattr = 0;
|
||||||
decl->pos = decl->top = 0;
|
decl->pos = decl->top = 0;
|
||||||
@ -1729,31 +1740,36 @@ static void cp_decl_multi(CPState *cp)
|
|||||||
cp_declarator(cp, &decl);
|
cp_declarator(cp, &decl);
|
||||||
typeid = cp_decl_intern(cp, &decl);
|
typeid = cp_decl_intern(cp, &decl);
|
||||||
if (decl.name && !decl.nameid) { /* NYI: redeclarations are ignored. */
|
if (decl.name && !decl.nameid) { /* NYI: redeclarations are ignored. */
|
||||||
|
CType *ct;
|
||||||
|
CTypeID id;
|
||||||
if ((scl & CDF_TYPEDEF)) { /* Create new typedef. */
|
if ((scl & CDF_TYPEDEF)) { /* Create new typedef. */
|
||||||
CType *ct;
|
id = lj_ctype_new(cp->cts, &ct);
|
||||||
CTypeID tdefid = lj_ctype_new(cp->cts, &ct);
|
|
||||||
ct->info = CTINFO(CT_TYPEDEF, typeid);
|
ct->info = CTINFO(CT_TYPEDEF, typeid);
|
||||||
ctype_setname(ct, decl.name);
|
goto noredir;
|
||||||
lj_ctype_addname(cp->cts, ct, tdefid);
|
|
||||||
} else if (ctype_isfunc(ctype_get(cp->cts, typeid)->info)) {
|
} else if (ctype_isfunc(ctype_get(cp->cts, typeid)->info)) {
|
||||||
/* Treat both static and extern function declarations as extern. */
|
/* Treat both static and extern function declarations as extern. */
|
||||||
CType *ct = ctype_get(cp->cts, typeid);
|
ct = ctype_get(cp->cts, typeid);
|
||||||
/* We always get new anonymous functions (typedefs are copied). */
|
/* We always get new anonymous functions (typedefs are copied). */
|
||||||
lua_assert(gcref(ct->name) == NULL);
|
lua_assert(gcref(ct->name) == NULL);
|
||||||
ctype_setname(ct, decl.name); /* Just name it. */
|
id = typeid; /* Just name it. */
|
||||||
lj_ctype_addname(cp->cts, ct, typeid);
|
|
||||||
} else if ((scl & CDF_STATIC)) { /* Accept static constants. */
|
} else if ((scl & CDF_STATIC)) { /* Accept static constants. */
|
||||||
CType *ct;
|
id = cp_decl_constinit(cp, &ct, typeid);
|
||||||
CTypeID constid = cp_decl_constinit(cp, &ct, typeid);
|
goto noredir;
|
||||||
ctype_setname(ct, decl.name);
|
|
||||||
lj_ctype_addname(cp->cts, ct, constid);
|
|
||||||
} else { /* External references have extern or no storage class. */
|
} else { /* External references have extern or no storage class. */
|
||||||
CType *ct;
|
id = lj_ctype_new(cp->cts, &ct);
|
||||||
CTypeID extid = lj_ctype_new(cp->cts, &ct);
|
|
||||||
ct->info = CTINFO(CT_EXTERN, typeid);
|
ct->info = CTINFO(CT_EXTERN, typeid);
|
||||||
ctype_setname(ct, decl.name);
|
|
||||||
lj_ctype_addname(cp->cts, ct, extid);
|
|
||||||
}
|
}
|
||||||
|
if (decl.redir) { /* Add attribute for redirected symbol name. */
|
||||||
|
CType *cta;
|
||||||
|
CTypeID aid = lj_ctype_new(cp->cts, &cta);
|
||||||
|
cta->info = CTINFO(CT_ATTRIB, CTATTRIB(CTA_REDIR));
|
||||||
|
cta->sib = ct->sib;
|
||||||
|
ct->sib = aid;
|
||||||
|
ctype_setname(cta, decl.redir);
|
||||||
|
}
|
||||||
|
noredir:
|
||||||
|
ctype_setname(ct, decl.name);
|
||||||
|
lj_ctype_addname(cp->cts, ct, id);
|
||||||
}
|
}
|
||||||
if (!cp_opt(cp, ',')) break;
|
if (!cp_opt(cp, ',')) break;
|
||||||
cp_decl_reset(&decl);
|
cp_decl_reset(&decl);
|
||||||
|
@ -54,7 +54,7 @@ LJ_STATIC_ASSERT(((int)CT_STRUCT & (int)CT_ARRAY) == CT_STRUCT);
|
|||||||
** |FIELD cid | offset | field | | name? |
|
** |FIELD cid | offset | field | | name? |
|
||||||
** |BITFIELD B.vcU csz bsz pos | offset | field | | name? |
|
** |BITFIELD B.vcU csz bsz pos | offset | field | | name? |
|
||||||
** |CONSTVAL c cid | value | const | name | name |
|
** |CONSTVAL c cid | value | const | name | name |
|
||||||
** |EXTERN cid | | | name | name |
|
** |EXTERN cid | | sib? | name | name |
|
||||||
** |KW tok | size | | name | name |
|
** |KW tok | size | | name | name |
|
||||||
** +----------------------------+--------+-------+-------+-------+--
|
** +----------------------------+--------+-------+-------+-------+--
|
||||||
** ^^ ^^--- bits used for C type conversion dispatch
|
** ^^ ^^--- bits used for C type conversion dispatch
|
||||||
@ -126,6 +126,7 @@ enum {
|
|||||||
CTA_QUAL, /* Unmerged qualifiers. */
|
CTA_QUAL, /* Unmerged qualifiers. */
|
||||||
CTA_ALIGN, /* Alignment override. */
|
CTA_ALIGN, /* Alignment override. */
|
||||||
CTA_SUBTYPE, /* Transparent sub-type. */
|
CTA_SUBTYPE, /* Transparent sub-type. */
|
||||||
|
CTA_REDIR, /* Redirected symbol name. */
|
||||||
CTA_BAD, /* To catch bad IDs. */
|
CTA_BAD, /* To catch bad IDs. */
|
||||||
CTA__MAX
|
CTA__MAX
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user