aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2011-01-26 02:31:19 +0100
committerMike Pall <mike>2011-01-26 02:31:19 +0100
commit1b75ec22c86259deaa02644fca5a096b432e145b (patch)
tree5d9ee055ba559aa0a48fcfe8f8bf1389659f93a9 /src
parented6c895ae56288b6982d1651c4ea638452c9e99b (diff)
downloadluajit-1b75ec22c86259deaa02644fca5a096b432e145b.tar.gz
luajit-1b75ec22c86259deaa02644fca5a096b432e145b.tar.bz2
luajit-1b75ec22c86259deaa02644fca5a096b432e145b.zip
FFI: Add symbol name redirection.
This works like the GCC extension, e.g.: FILE *fopen(const char *fn, const char *mode) __asm__("" "fopen64");
Diffstat (limited to 'src')
-rw-r--r--src/lj_ccall.c10
-rw-r--r--src/lj_clib.c18
-rw-r--r--src/lj_cparse.c48
-rw-r--r--src/lj_ctype.h3
4 files changed, 58 insertions, 21 deletions
diff --git a/src/lj_ccall.c b/src/lj_ccall.c
index 6234a05a..3881ad50 100644
--- a/src/lj_ccall.c
+++ b/src/lj_ccall.c
@@ -275,8 +275,16 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
275#endif 275#endif
276 } 276 }
277 277
278 /* Skip initial attributes. */
279 fid = ct->sib;
280 while (fid) {
281 CType *ctf = ctype_get(cts, fid);
282 if (!ctype_isattrib(ctf->info)) break;
283 fid = ctf->sib;
284 }
285
278 /* Walk through all passed arguments. */ 286 /* Walk through all passed arguments. */
279 for (fid = ct->sib, o = L->base+1; o < top; o++) { 287 for (o = L->base+1; o < top; o++) {
280 CTypeID did; 288 CTypeID did;
281 CType *d; 289 CType *d;
282 CTSize sz; 290 CTSize sz;
diff --git a/src/lj_clib.c b/src/lj_clib.c
index 4a81bb7d..e2d349fd 100644
--- a/src/lj_clib.c
+++ b/src/lj_clib.c
@@ -242,6 +242,17 @@ static CTSize clib_func_argsize(CTState *cts, CType *ct)
242} 242}
243#endif 243#endif
244 244
245/* Get redirected or mangled external symbol. */
246static const char *clib_extsym(CTState *cts, CType *ct, GCstr *name)
247{
248 if (ct->sib) {
249 CType *ctf = ctype_get(cts, ct->sib);
250 if (ctype_isxattrib(ctf->info, CTA_REDIR))
251 return strdata(gco2str(gcref(ctf->name)));
252 }
253 return strdata(name);
254}
255
245/* Index a C library by name. */ 256/* Index a C library by name. */
246TValue *lj_clib_index(lua_State *L, CLibrary *cl, GCstr *name) 257TValue *lj_clib_index(lua_State *L, CLibrary *cl, GCstr *name)
247{ 258{
@@ -260,7 +271,8 @@ TValue *lj_clib_index(lua_State *L, CLibrary *cl, GCstr *name)
260 else 271 else
261 setnumV(tv, (lua_Number)(int32_t)ct->size); 272 setnumV(tv, (lua_Number)(int32_t)ct->size);
262 } else { 273 } else {
263 void *p = clib_getsym(cl, strdata(name)); 274 const char *sym = clib_extsym(cts, ct, name);
275 void *p = clib_getsym(cl, sym);
264 GCcdata *cd; 276 GCcdata *cd;
265 lua_assert(ctype_isfunc(ct->info) || ctype_isextern(ct->info)); 277 lua_assert(ctype_isfunc(ct->info) || ctype_isextern(ct->info));
266#if LJ_TARGET_X86 && LJ_ABI_WIN 278#if LJ_TARGET_X86 && LJ_ABI_WIN
@@ -269,8 +281,8 @@ TValue *lj_clib_index(lua_State *L, CLibrary *cl, GCstr *name)
269 CTInfo cconv = ctype_cconv(ct->info); 281 CTInfo cconv = ctype_cconv(ct->info);
270 if (cconv == CTCC_FASTCALL || cconv == CTCC_STDCALL) { 282 if (cconv == CTCC_FASTCALL || cconv == CTCC_STDCALL) {
271 CTSize sz = clib_func_argsize(cts, ct); 283 CTSize sz = clib_func_argsize(cts, ct);
272 const char *sym = lj_str_pushf(L, 284 sym = lj_str_pushf(L, cconv == CTCC_FASTCALL ? "@%s@%d" : "_%s@%d",
273 cconv == CTCC_FASTCALL ? "@%s@%d" : "_%s@%d", strdata(name), sz); 285 sym, sz);
274 L->top--; 286 L->top--;
275 p = clib_getsym(cl, sym); 287 p = clib_getsym(cl, sym);
276 } 288 }
diff --git a/src/lj_cparse.c b/src/lj_cparse.c
index 333e7a07..925894a3 100644
--- a/src/lj_cparse.c
+++ b/src/lj_cparse.c
@@ -342,6 +342,7 @@ typedef struct CPDecl {
342 uint32_t mode; /* Declarator mode. */ 342 uint32_t mode; /* Declarator mode. */
343 CPState *cp; /* C parser state. */ 343 CPState *cp; /* C parser state. */
344 GCstr *name; /* Name of declared identifier (if direct). */ 344 GCstr *name; /* Name of declared identifier (if direct). */
345 GCstr *redir; /* Redirected symbol name. */
345 CTypeID nameid; /* Existing typedef for declared identifier. */ 346 CTypeID nameid; /* Existing typedef for declared identifier. */
346 CTInfo attr; /* Attributes. */ 347 CTInfo attr; /* Attributes. */
347 CTInfo fattr; /* Function attributes. */ 348 CTInfo fattr; /* Function attributes. */
@@ -923,6 +924,7 @@ static void cp_decl_reset(CPDecl *decl)
923 decl->attr = decl->specattr; 924 decl->attr = decl->specattr;
924 decl->fattr = decl->specfattr; 925 decl->fattr = decl->specfattr;
925 decl->name = NULL; 926 decl->name = NULL;
927 decl->redir = NULL;
926} 928}
927 929
928/* Parse constant initializer. */ 930/* Parse constant initializer. */
@@ -982,7 +984,15 @@ static void cp_decl_asm(CPState *cp, CPDecl *decl)
982 UNUSED(decl); 984 UNUSED(decl);
983 cp_next(cp); 985 cp_next(cp);
984 cp_check(cp, '('); 986 cp_check(cp, '(');
985 while (cp->tok == CTOK_STRING) cp_next(cp); /* NYI: currently ignored. */ 987 if (cp->tok == CTOK_STRING) {
988 GCstr *str = cp->str;
989 while (cp_next(cp) == CTOK_STRING) {
990 lj_str_pushf(cp->L, "%s%s", strdata(str), strdata(cp->str));
991 cp->L->top--;
992 str = strV(cp->L->top);
993 }
994 decl->redir = str;
995 }
986 cp_check(cp, ')'); 996 cp_check(cp, ')');
987} 997}
988 998
@@ -1428,6 +1438,7 @@ static CPscl cp_decl_spec(CPState *cp, CPDecl *decl, CPscl scl)
1428 decl->cp = cp; 1438 decl->cp = cp;
1429 decl->mode = cp->mode; 1439 decl->mode = cp->mode;
1430 decl->name = NULL; 1440 decl->name = NULL;
1441 decl->redir = NULL;
1431 decl->attr = 0; 1442 decl->attr = 0;
1432 decl->fattr = 0; 1443 decl->fattr = 0;
1433 decl->pos = decl->top = 0; 1444 decl->pos = decl->top = 0;
@@ -1729,31 +1740,36 @@ static void cp_decl_multi(CPState *cp)
1729 cp_declarator(cp, &decl); 1740 cp_declarator(cp, &decl);
1730 typeid = cp_decl_intern(cp, &decl); 1741 typeid = cp_decl_intern(cp, &decl);
1731 if (decl.name && !decl.nameid) { /* NYI: redeclarations are ignored. */ 1742 if (decl.name && !decl.nameid) { /* NYI: redeclarations are ignored. */
1743 CType *ct;
1744 CTypeID id;
1732 if ((scl & CDF_TYPEDEF)) { /* Create new typedef. */ 1745 if ((scl & CDF_TYPEDEF)) { /* Create new typedef. */
1733 CType *ct; 1746 id = lj_ctype_new(cp->cts, &ct);
1734 CTypeID tdefid = lj_ctype_new(cp->cts, &ct);
1735 ct->info = CTINFO(CT_TYPEDEF, typeid); 1747 ct->info = CTINFO(CT_TYPEDEF, typeid);
1736 ctype_setname(ct, decl.name); 1748 goto noredir;
1737 lj_ctype_addname(cp->cts, ct, tdefid);
1738 } else if (ctype_isfunc(ctype_get(cp->cts, typeid)->info)) { 1749 } else if (ctype_isfunc(ctype_get(cp->cts, typeid)->info)) {
1739 /* Treat both static and extern function declarations as extern. */ 1750 /* Treat both static and extern function declarations as extern. */
1740 CType *ct = ctype_get(cp->cts, typeid); 1751 ct = ctype_get(cp->cts, typeid);
1741 /* We always get new anonymous functions (typedefs are copied). */ 1752 /* We always get new anonymous functions (typedefs are copied). */
1742 lua_assert(gcref(ct->name) == NULL); 1753 lua_assert(gcref(ct->name) == NULL);
1743 ctype_setname(ct, decl.name); /* Just name it. */ 1754 id = typeid; /* Just name it. */
1744 lj_ctype_addname(cp->cts, ct, typeid);
1745 } else if ((scl & CDF_STATIC)) { /* Accept static constants. */ 1755 } else if ((scl & CDF_STATIC)) { /* Accept static constants. */
1746 CType *ct; 1756 id = cp_decl_constinit(cp, &ct, typeid);
1747 CTypeID constid = cp_decl_constinit(cp, &ct, typeid); 1757 goto noredir;
1748 ctype_setname(ct, decl.name);
1749 lj_ctype_addname(cp->cts, ct, constid);
1750 } else { /* External references have extern or no storage class. */ 1758 } else { /* External references have extern or no storage class. */
1751 CType *ct; 1759 id = lj_ctype_new(cp->cts, &ct);
1752 CTypeID extid = lj_ctype_new(cp->cts, &ct);
1753 ct->info = CTINFO(CT_EXTERN, typeid); 1760 ct->info = CTINFO(CT_EXTERN, typeid);
1754 ctype_setname(ct, decl.name);
1755 lj_ctype_addname(cp->cts, ct, extid);
1756 } 1761 }
1762 if (decl.redir) { /* Add attribute for redirected symbol name. */
1763 CType *cta;
1764 CTypeID aid = lj_ctype_new(cp->cts, &cta);
1765 cta->info = CTINFO(CT_ATTRIB, CTATTRIB(CTA_REDIR));
1766 cta->sib = ct->sib;
1767 ct->sib = aid;
1768 ctype_setname(cta, decl.redir);
1769 }
1770 noredir:
1771 ctype_setname(ct, decl.name);
1772 lj_ctype_addname(cp->cts, ct, id);
1757 } 1773 }
1758 if (!cp_opt(cp, ',')) break; 1774 if (!cp_opt(cp, ',')) break;
1759 cp_decl_reset(&decl); 1775 cp_decl_reset(&decl);
diff --git a/src/lj_ctype.h b/src/lj_ctype.h
index 17a6fdc3..555393db 100644
--- a/src/lj_ctype.h
+++ b/src/lj_ctype.h
@@ -54,7 +54,7 @@ LJ_STATIC_ASSERT(((int)CT_STRUCT & (int)CT_ARRAY) == CT_STRUCT);
54** |FIELD cid | offset | field | | name? | 54** |FIELD cid | offset | field | | name? |
55** |BITFIELD B.vcU csz bsz pos | offset | field | | name? | 55** |BITFIELD B.vcU csz bsz pos | offset | field | | name? |
56** |CONSTVAL c cid | value | const | name | name | 56** |CONSTVAL c cid | value | const | name | name |
57** |EXTERN cid | | | name | name | 57** |EXTERN cid | | sib? | name | name |
58** |KW tok | size | | name | name | 58** |KW tok | size | | name | name |
59** +----------------------------+--------+-------+-------+-------+-- 59** +----------------------------+--------+-------+-------+-------+--
60** ^^ ^^--- bits used for C type conversion dispatch 60** ^^ ^^--- bits used for C type conversion dispatch
@@ -126,6 +126,7 @@ enum {
126 CTA_QUAL, /* Unmerged qualifiers. */ 126 CTA_QUAL, /* Unmerged qualifiers. */
127 CTA_ALIGN, /* Alignment override. */ 127 CTA_ALIGN, /* Alignment override. */
128 CTA_SUBTYPE, /* Transparent sub-type. */ 128 CTA_SUBTYPE, /* Transparent sub-type. */
129 CTA_REDIR, /* Redirected symbol name. */
129 CTA_BAD, /* To catch bad IDs. */ 130 CTA_BAD, /* To catch bad IDs. */
130 CTA__MAX 131 CTA__MAX
131}; 132};