diff options
author | Mike Pall <mike> | 2012-06-14 19:54:07 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2012-06-14 19:54:07 +0200 |
commit | 946c7418d59dd201386ee66686075595754cd86d (patch) | |
tree | 1930adb8b7f969b8b69ed3b634fd1736e7d5944e /src/lj_cparse.c | |
parent | ca6bf2d9a41fb2c0c80bafdbaf2e29421b2cb55d (diff) | |
download | luajit-946c7418d59dd201386ee66686075595754cd86d.tar.gz luajit-946c7418d59dd201386ee66686075595754cd86d.tar.bz2 luajit-946c7418d59dd201386ee66686075595754cd86d.zip |
FFI: Add support for parameterized C types.
Diffstat (limited to 'src/lj_cparse.c')
-rw-r--r-- | src/lj_cparse.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/src/lj_cparse.c b/src/lj_cparse.c index ff5abc70..0f8c2857 100644 --- a/src/lj_cparse.c +++ b/src/lj_cparse.c | |||
@@ -121,6 +121,7 @@ LJ_NORET static void cp_errmsg(CPState *cp, CPToken tok, ErrMsg em, ...) | |||
121 | tokstr = NULL; | 121 | tokstr = NULL; |
122 | } else if (tok == CTOK_IDENT || tok == CTOK_INTEGER || tok == CTOK_STRING || | 122 | } else if (tok == CTOK_IDENT || tok == CTOK_INTEGER || tok == CTOK_STRING || |
123 | tok >= CTOK_FIRSTDECL) { | 123 | tok >= CTOK_FIRSTDECL) { |
124 | if (cp->sb.n == 0) cp_save(cp, '$'); | ||
124 | cp_save(cp, '\0'); | 125 | cp_save(cp, '\0'); |
125 | tokstr = cp->sb.buf; | 126 | tokstr = cp->sb.buf; |
126 | } else { | 127 | } else { |
@@ -203,6 +204,38 @@ static CPToken cp_ident(CPState *cp) | |||
203 | return CTOK_IDENT; | 204 | return CTOK_IDENT; |
204 | } | 205 | } |
205 | 206 | ||
207 | /* Parse parameter. */ | ||
208 | static CPToken cp_param(CPState *cp) | ||
209 | { | ||
210 | CPChar c = cp_get(cp); | ||
211 | TValue *o = cp->param; | ||
212 | if (lj_char_isident(c) || c == '$') /* Reserve $xyz for future extensions. */ | ||
213 | cp_errmsg(cp, c, LJ_ERR_XSYNTAX); | ||
214 | if (!o || o >= cp->L->top) | ||
215 | cp_err(cp, LJ_ERR_FFI_NUMPARAM); | ||
216 | cp->param = o+1; | ||
217 | if (tvisstr(o)) { | ||
218 | cp->str = strV(o); | ||
219 | cp->val.id = lj_ctype_getname(cp->cts, &cp->ct, cp->str, cp->tmask); | ||
220 | if (ctype_type(cp->ct->info) == CT_KW) | ||
221 | return ctype_cid(cp->ct->info); | ||
222 | return CTOK_IDENT; | ||
223 | } else if (tvisnumber(o)) { | ||
224 | cp->val.i32 = numberVint(o); | ||
225 | cp->val.id = CTID_INT32; | ||
226 | return CTOK_INTEGER; | ||
227 | } else { | ||
228 | GCcdata *cd; | ||
229 | if (!tviscdata(o)) lj_err_argtype(cp->L, o-cp->L->base+1, "type parameter"); | ||
230 | cd = cdataV(o); | ||
231 | if (cd->typeid == CTID_CTYPEID) | ||
232 | cp->val.id = *(CTypeID *)cdataptr(cd); | ||
233 | else | ||
234 | cp->val.id = cd->typeid; | ||
235 | return '$'; | ||
236 | } | ||
237 | } | ||
238 | |||
206 | /* Parse string or character constant. */ | 239 | /* Parse string or character constant. */ |
207 | static CPToken cp_string(CPState *cp) | 240 | static CPToken cp_string(CPState *cp) |
208 | { | 241 | { |
@@ -317,6 +350,8 @@ static CPToken cp_next_(CPState *cp) | |||
317 | return '>'; | 350 | return '>'; |
318 | case '-': | 351 | case '-': |
319 | cp_get(cp); if (cp->c != '>') return '-'; cp_get(cp); return CTOK_DEREF; | 352 | cp_get(cp); if (cp->c != '>') return '-'; cp_get(cp); return CTOK_DEREF; |
353 | case '$': | ||
354 | return cp_param(cp); | ||
320 | case '\0': return CTOK_EOF; | 355 | case '\0': return CTOK_EOF; |
321 | default: { CPToken c = cp->c; cp_get(cp); return c; } | 356 | default: { CPToken c = cp->c; cp_get(cp); return c; } |
322 | } | 357 | } |
@@ -403,6 +438,7 @@ static int cp_istypedecl(CPState *cp) | |||
403 | { | 438 | { |
404 | if (cp->tok >= CTOK_FIRSTDECL && cp->tok <= CTOK_LASTDECL) return 1; | 439 | if (cp->tok >= CTOK_FIRSTDECL && cp->tok <= CTOK_LASTDECL) return 1; |
405 | if (cp->tok == CTOK_IDENT && ctype_istypedef(cp->ct->info)) return 1; | 440 | if (cp->tok == CTOK_IDENT && ctype_istypedef(cp->ct->info)) return 1; |
441 | if (cp->tok == '$') return 1; | ||
406 | return 0; | 442 | return 0; |
407 | } | 443 | } |
408 | 444 | ||
@@ -1441,7 +1477,7 @@ static CTypeID cp_decl_enum(CPState *cp, CPDecl *sdecl) | |||
1441 | static CPscl cp_decl_spec(CPState *cp, CPDecl *decl, CPscl scl) | 1477 | static CPscl cp_decl_spec(CPState *cp, CPDecl *decl, CPscl scl) |
1442 | { | 1478 | { |
1443 | uint32_t cds = 0, sz = 0; | 1479 | uint32_t cds = 0, sz = 0; |
1444 | CTInfo tdef = 0; | 1480 | CTypeID tdef = 0; |
1445 | 1481 | ||
1446 | decl->cp = cp; | 1482 | decl->cp = cp; |
1447 | decl->mode = cp->mode; | 1483 | decl->mode = cp->mode; |
@@ -1471,6 +1507,10 @@ static CPscl cp_decl_spec(CPState *cp, CPDecl *decl, CPscl scl) | |||
1471 | tdef = ctype_cid(cp->ct->info); /* Get typedef. */ | 1507 | tdef = ctype_cid(cp->ct->info); /* Get typedef. */ |
1472 | cp_next(cp); | 1508 | cp_next(cp); |
1473 | break; | 1509 | break; |
1510 | case '$': | ||
1511 | tdef = cp->val.id; | ||
1512 | cp_next(cp); | ||
1513 | break; | ||
1474 | default: | 1514 | default: |
1475 | if (cp->tok >= CTOK_FIRSTDECL && cp->tok <= CTOK_LASTDECLFLAG) { | 1515 | if (cp->tok >= CTOK_FIRSTDECL && cp->tok <= CTOK_LASTDECLFLAG) { |
1476 | uint32_t cbit; | 1516 | uint32_t cbit; |
@@ -1826,6 +1866,8 @@ static TValue *cpcparser(lua_State *L, lua_CFunction dummy, void *ud) | |||
1826 | cp_decl_multi(cp); | 1866 | cp_decl_multi(cp); |
1827 | else | 1867 | else |
1828 | cp_decl_single(cp); | 1868 | cp_decl_single(cp); |
1869 | if (cp->param && cp->param != cp->L->top) | ||
1870 | cp_err(cp, LJ_ERR_FFI_NUMPARAM); | ||
1829 | lua_assert(cp->depth == 0); | 1871 | lua_assert(cp->depth == 0); |
1830 | return NULL; | 1872 | return NULL; |
1831 | } | 1873 | } |