diff options
author | Mike Pall <mike> | 2011-01-26 02:31:19 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2011-01-26 02:31:19 +0100 |
commit | 1b75ec22c86259deaa02644fca5a096b432e145b (patch) | |
tree | 5d9ee055ba559aa0a48fcfe8f8bf1389659f93a9 /src | |
parent | ed6c895ae56288b6982d1651c4ea638452c9e99b (diff) | |
download | luajit-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.c | 10 | ||||
-rw-r--r-- | src/lj_clib.c | 18 | ||||
-rw-r--r-- | src/lj_cparse.c | 48 | ||||
-rw-r--r-- | src/lj_ctype.h | 3 |
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. */ | ||
246 | static 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. */ |
246 | TValue *lj_clib_index(lua_State *L, CLibrary *cl, GCstr *name) | 257 | TValue *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 | }; |