lj_cparse.c (56983B)
1 /* 2 ** C declaration parser. 3 ** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h 4 */ 5 6 #include "lj_obj.h" 7 8 #if LJ_HASFFI 9 10 #include "lj_gc.h" 11 #include "lj_err.h" 12 #include "lj_buf.h" 13 #include "lj_ctype.h" 14 #include "lj_cparse.h" 15 #include "lj_frame.h" 16 #include "lj_vm.h" 17 #include "lj_char.h" 18 #include "lj_strscan.h" 19 #include "lj_strfmt.h" 20 21 /* 22 ** Important note: this is NOT a validating C parser! This is a minimal 23 ** C declaration parser, solely for use by the LuaJIT FFI. 24 ** 25 ** It ought to return correct results for properly formed C declarations, 26 ** but it may accept some invalid declarations, too (and return nonsense). 27 ** Also, it shows rather generic error messages to avoid unnecessary bloat. 28 ** If in doubt, please check the input against your favorite C compiler. 29 */ 30 31 /* -- C lexer ------------------------------------------------------------- */ 32 33 /* C lexer token names. */ 34 static const char *const ctoknames[] = { 35 #define CTOKSTR(name, str) str, 36 CTOKDEF(CTOKSTR) 37 #undef CTOKSTR 38 NULL 39 }; 40 41 /* Forward declaration. */ 42 LJ_NORET static void cp_err(CPState *cp, ErrMsg em); 43 44 static const char *cp_tok2str(CPState *cp, CPToken tok) 45 { 46 lua_assert(tok < CTOK_FIRSTDECL); 47 if (tok > CTOK_OFS) 48 return ctoknames[tok-CTOK_OFS-1]; 49 else if (!lj_char_iscntrl(tok)) 50 return lj_strfmt_pushf(cp->L, "%c", tok); 51 else 52 return lj_strfmt_pushf(cp->L, "char(%d)", tok); 53 } 54 55 /* End-of-line? */ 56 static LJ_AINLINE int cp_iseol(CPChar c) 57 { 58 return (c == '\n' || c == '\r'); 59 } 60 61 /* Peek next raw character. */ 62 static LJ_AINLINE CPChar cp_rawpeek(CPState *cp) 63 { 64 return (CPChar)(uint8_t)(*cp->p); 65 } 66 67 static LJ_NOINLINE CPChar cp_get_bs(CPState *cp); 68 69 /* Get next character. */ 70 static LJ_AINLINE CPChar cp_get(CPState *cp) 71 { 72 cp->c = (CPChar)(uint8_t)(*cp->p++); 73 if (LJ_LIKELY(cp->c != '\\')) return cp->c; 74 return cp_get_bs(cp); 75 } 76 77 /* Transparently skip backslash-escaped line breaks. */ 78 static LJ_NOINLINE CPChar cp_get_bs(CPState *cp) 79 { 80 CPChar c2, c = cp_rawpeek(cp); 81 if (!cp_iseol(c)) return cp->c; 82 cp->p++; 83 c2 = cp_rawpeek(cp); 84 if (cp_iseol(c2) && c2 != c) cp->p++; 85 cp->linenumber++; 86 return cp_get(cp); 87 } 88 89 /* Save character in buffer. */ 90 static LJ_AINLINE void cp_save(CPState *cp, CPChar c) 91 { 92 lj_buf_putb(&cp->sb, c); 93 } 94 95 /* Skip line break. Handles "\n", "\r", "\r\n" or "\n\r". */ 96 static void cp_newline(CPState *cp) 97 { 98 CPChar c = cp_rawpeek(cp); 99 if (cp_iseol(c) && c != cp->c) cp->p++; 100 cp->linenumber++; 101 } 102 103 LJ_NORET static void cp_errmsg(CPState *cp, CPToken tok, ErrMsg em, ...) 104 { 105 const char *msg, *tokstr; 106 lua_State *L; 107 va_list argp; 108 if (tok == 0) { 109 tokstr = NULL; 110 } else if (tok == CTOK_IDENT || tok == CTOK_INTEGER || tok == CTOK_STRING || 111 tok >= CTOK_FIRSTDECL) { 112 if (sbufP(&cp->sb) == sbufB(&cp->sb)) cp_save(cp, '$'); 113 cp_save(cp, '\0'); 114 tokstr = sbufB(&cp->sb); 115 } else { 116 tokstr = cp_tok2str(cp, tok); 117 } 118 L = cp->L; 119 va_start(argp, em); 120 msg = lj_strfmt_pushvf(L, err2msg(em), argp); 121 va_end(argp); 122 if (tokstr) 123 msg = lj_strfmt_pushf(L, err2msg(LJ_ERR_XNEAR), msg, tokstr); 124 if (cp->linenumber > 1) 125 msg = lj_strfmt_pushf(L, "%s at line %d", msg, cp->linenumber); 126 lj_err_callermsg(L, msg); 127 } 128 129 LJ_NORET LJ_NOINLINE static void cp_err_token(CPState *cp, CPToken tok) 130 { 131 cp_errmsg(cp, cp->tok, LJ_ERR_XTOKEN, cp_tok2str(cp, tok)); 132 } 133 134 LJ_NORET LJ_NOINLINE static void cp_err_badidx(CPState *cp, CType *ct) 135 { 136 GCstr *s = lj_ctype_repr(cp->cts->L, ctype_typeid(cp->cts, ct), NULL); 137 cp_errmsg(cp, 0, LJ_ERR_FFI_BADIDX, strdata(s)); 138 } 139 140 LJ_NORET LJ_NOINLINE static void cp_err(CPState *cp, ErrMsg em) 141 { 142 cp_errmsg(cp, 0, em); 143 } 144 145 /* -- Main lexical scanner ------------------------------------------------ */ 146 147 /* Parse number literal. Only handles int32_t/uint32_t right now. */ 148 static CPToken cp_number(CPState *cp) 149 { 150 StrScanFmt fmt; 151 TValue o; 152 do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp))); 153 cp_save(cp, '\0'); 154 fmt = lj_strscan_scan((const uint8_t *)sbufB(&cp->sb), &o, STRSCAN_OPT_C); 155 if (fmt == STRSCAN_INT) cp->val.id = CTID_INT32; 156 else if (fmt == STRSCAN_U32) cp->val.id = CTID_UINT32; 157 else if (!(cp->mode & CPARSE_MODE_SKIP)) 158 cp_errmsg(cp, CTOK_INTEGER, LJ_ERR_XNUMBER); 159 cp->val.u32 = (uint32_t)o.i; 160 return CTOK_INTEGER; 161 } 162 163 /* Parse identifier or keyword. */ 164 static CPToken cp_ident(CPState *cp) 165 { 166 do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp))); 167 cp->str = lj_buf_str(cp->L, &cp->sb); 168 cp->val.id = lj_ctype_getname(cp->cts, &cp->ct, cp->str, cp->tmask); 169 if (ctype_type(cp->ct->info) == CT_KW) 170 return ctype_cid(cp->ct->info); 171 return CTOK_IDENT; 172 } 173 174 /* Parse parameter. */ 175 static CPToken cp_param(CPState *cp) 176 { 177 CPChar c = cp_get(cp); 178 TValue *o = cp->param; 179 if (lj_char_isident(c) || c == '$') /* Reserve $xyz for future extensions. */ 180 cp_errmsg(cp, c, LJ_ERR_XSYNTAX); 181 if (!o || o >= cp->L->top) 182 cp_err(cp, LJ_ERR_FFI_NUMPARAM); 183 cp->param = o+1; 184 if (tvisstr(o)) { 185 cp->str = strV(o); 186 cp->val.id = 0; 187 cp->ct = &cp->cts->tab[0]; 188 return CTOK_IDENT; 189 } else if (tvisnumber(o)) { 190 cp->val.i32 = numberVint(o); 191 cp->val.id = CTID_INT32; 192 return CTOK_INTEGER; 193 } else { 194 GCcdata *cd; 195 if (!tviscdata(o)) 196 lj_err_argtype(cp->L, (int)(o-cp->L->base)+1, "type parameter"); 197 cd = cdataV(o); 198 if (cd->ctypeid == CTID_CTYPEID) 199 cp->val.id = *(CTypeID *)cdataptr(cd); 200 else 201 cp->val.id = cd->ctypeid; 202 return '$'; 203 } 204 } 205 206 /* Parse string or character constant. */ 207 static CPToken cp_string(CPState *cp) 208 { 209 CPChar delim = cp->c; 210 cp_get(cp); 211 while (cp->c != delim) { 212 CPChar c = cp->c; 213 if (c == '\0') cp_errmsg(cp, CTOK_EOF, LJ_ERR_XSTR); 214 if (c == '\\') { 215 c = cp_get(cp); 216 switch (c) { 217 case '\0': cp_errmsg(cp, CTOK_EOF, LJ_ERR_XSTR); break; 218 case 'a': c = '\a'; break; 219 case 'b': c = '\b'; break; 220 case 'f': c = '\f'; break; 221 case 'n': c = '\n'; break; 222 case 'r': c = '\r'; break; 223 case 't': c = '\t'; break; 224 case 'v': c = '\v'; break; 225 case 'e': c = 27; break; 226 case 'x': 227 c = 0; 228 while (lj_char_isxdigit(cp_get(cp))) 229 c = (c<<4) + (lj_char_isdigit(cp->c) ? cp->c-'0' : (cp->c&15)+9); 230 cp_save(cp, (c & 0xff)); 231 continue; 232 default: 233 if (lj_char_isdigit(c)) { 234 c -= '0'; 235 if (lj_char_isdigit(cp_get(cp))) { 236 c = c*8 + (cp->c - '0'); 237 if (lj_char_isdigit(cp_get(cp))) { 238 c = c*8 + (cp->c - '0'); 239 cp_get(cp); 240 } 241 } 242 cp_save(cp, (c & 0xff)); 243 continue; 244 } 245 break; 246 } 247 } 248 cp_save(cp, c); 249 cp_get(cp); 250 } 251 cp_get(cp); 252 if (delim == '"') { 253 cp->str = lj_buf_str(cp->L, &cp->sb); 254 return CTOK_STRING; 255 } else { 256 if (sbuflen(&cp->sb) != 1) cp_err_token(cp, '\''); 257 cp->val.i32 = (int32_t)(char)*sbufB(&cp->sb); 258 cp->val.id = CTID_INT32; 259 return CTOK_INTEGER; 260 } 261 } 262 263 /* Skip C comment. */ 264 static void cp_comment_c(CPState *cp) 265 { 266 do { 267 if (cp_get(cp) == '*') { 268 do { 269 if (cp_get(cp) == '/') { cp_get(cp); return; } 270 } while (cp->c == '*'); 271 } 272 if (cp_iseol(cp->c)) cp_newline(cp); 273 } while (cp->c != '\0'); 274 } 275 276 /* Skip C++ comment. */ 277 static void cp_comment_cpp(CPState *cp) 278 { 279 while (!cp_iseol(cp_get(cp)) && cp->c != '\0') 280 ; 281 } 282 283 /* Lexical scanner for C. Only a minimal subset is implemented. */ 284 static CPToken cp_next_(CPState *cp) 285 { 286 lj_buf_reset(&cp->sb); 287 for (;;) { 288 if (lj_char_isident(cp->c)) 289 return lj_char_isdigit(cp->c) ? cp_number(cp) : cp_ident(cp); 290 switch (cp->c) { 291 case '\n': case '\r': cp_newline(cp); /* fallthrough. */ 292 case ' ': case '\t': case '\v': case '\f': cp_get(cp); break; 293 case '"': case '\'': return cp_string(cp); 294 case '/': 295 if (cp_get(cp) == '*') cp_comment_c(cp); 296 else if (cp->c == '/') cp_comment_cpp(cp); 297 else return '/'; 298 break; 299 case '|': 300 if (cp_get(cp) != '|') return '|'; 301 cp_get(cp); return CTOK_OROR; 302 case '&': 303 if (cp_get(cp) != '&') return '&'; 304 cp_get(cp); return CTOK_ANDAND; 305 case '=': 306 if (cp_get(cp) != '=') return '='; 307 cp_get(cp); return CTOK_EQ; 308 case '!': 309 if (cp_get(cp) != '=') return '!'; 310 cp_get(cp); return CTOK_NE; 311 case '<': 312 if (cp_get(cp) == '=') { cp_get(cp); return CTOK_LE; } 313 else if (cp->c == '<') { cp_get(cp); return CTOK_SHL; } 314 return '<'; 315 case '>': 316 if (cp_get(cp) == '=') { cp_get(cp); return CTOK_GE; } 317 else if (cp->c == '>') { cp_get(cp); return CTOK_SHR; } 318 return '>'; 319 case '-': 320 if (cp_get(cp) != '>') return '-'; 321 cp_get(cp); return CTOK_DEREF; 322 case '$': 323 return cp_param(cp); 324 case '\0': return CTOK_EOF; 325 default: { CPToken c = cp->c; cp_get(cp); return c; } 326 } 327 } 328 } 329 330 static LJ_NOINLINE CPToken cp_next(CPState *cp) 331 { 332 return (cp->tok = cp_next_(cp)); 333 } 334 335 /* -- C parser ------------------------------------------------------------ */ 336 337 /* Namespaces for resolving identifiers. */ 338 #define CPNS_DEFAULT \ 339 ((1u<<CT_KW)|(1u<<CT_TYPEDEF)|(1u<<CT_FUNC)|(1u<<CT_EXTERN)|(1u<<CT_CONSTVAL)) 340 #define CPNS_STRUCT ((1u<<CT_KW)|(1u<<CT_STRUCT)|(1u<<CT_ENUM)) 341 342 typedef CTypeID CPDeclIdx; /* Index into declaration stack. */ 343 typedef uint32_t CPscl; /* Storage class flags. */ 344 345 /* Type declaration context. */ 346 typedef struct CPDecl { 347 CPDeclIdx top; /* Top of declaration stack. */ 348 CPDeclIdx pos; /* Insertion position in declaration chain. */ 349 CPDeclIdx specpos; /* Saved position for declaration specifier. */ 350 uint32_t mode; /* Declarator mode. */ 351 CPState *cp; /* C parser state. */ 352 GCstr *name; /* Name of declared identifier (if direct). */ 353 GCstr *redir; /* Redirected symbol name. */ 354 CTypeID nameid; /* Existing typedef for declared identifier. */ 355 CTInfo attr; /* Attributes. */ 356 CTInfo fattr; /* Function attributes. */ 357 CTInfo specattr; /* Saved attributes. */ 358 CTInfo specfattr; /* Saved function attributes. */ 359 CTSize bits; /* Field size in bits (if any). */ 360 CType stack[CPARSE_MAX_DECLSTACK]; /* Type declaration stack. */ 361 } CPDecl; 362 363 /* Forward declarations. */ 364 static CPscl cp_decl_spec(CPState *cp, CPDecl *decl, CPscl scl); 365 static void cp_declarator(CPState *cp, CPDecl *decl); 366 static CTypeID cp_decl_abstract(CPState *cp); 367 368 /* Initialize C parser state. Caller must set up: L, p, srcname, mode. */ 369 static void cp_init(CPState *cp) 370 { 371 cp->linenumber = 1; 372 cp->depth = 0; 373 cp->curpack = 0; 374 cp->packstack[0] = 255; 375 lj_buf_init(cp->L, &cp->sb); 376 lua_assert(cp->p != NULL); 377 cp_get(cp); /* Read-ahead first char. */ 378 cp->tok = 0; 379 cp->tmask = CPNS_DEFAULT; 380 cp_next(cp); /* Read-ahead first token. */ 381 } 382 383 /* Cleanup C parser state. */ 384 static void cp_cleanup(CPState *cp) 385 { 386 global_State *g = G(cp->L); 387 lj_buf_free(g, &cp->sb); 388 } 389 390 /* Check and consume optional token. */ 391 static int cp_opt(CPState *cp, CPToken tok) 392 { 393 if (cp->tok == tok) { cp_next(cp); return 1; } 394 return 0; 395 } 396 397 /* Check and consume token. */ 398 static void cp_check(CPState *cp, CPToken tok) 399 { 400 if (cp->tok != tok) cp_err_token(cp, tok); 401 cp_next(cp); 402 } 403 404 /* Check if the next token may start a type declaration. */ 405 static int cp_istypedecl(CPState *cp) 406 { 407 if (cp->tok >= CTOK_FIRSTDECL && cp->tok <= CTOK_LASTDECL) return 1; 408 if (cp->tok == CTOK_IDENT && ctype_istypedef(cp->ct->info)) return 1; 409 if (cp->tok == '$') return 1; 410 return 0; 411 } 412 413 /* -- Constant expression evaluator --------------------------------------- */ 414 415 /* Forward declarations. */ 416 static void cp_expr_unary(CPState *cp, CPValue *k); 417 static void cp_expr_sub(CPState *cp, CPValue *k, int pri); 418 419 /* Please note that type handling is very weak here. Most ops simply 420 ** assume integer operands. Accessors are only needed to compute types and 421 ** return synthetic values. The only purpose of the expression evaluator 422 ** is to compute the values of constant expressions one would typically 423 ** find in C header files. And again: this is NOT a validating C parser! 424 */ 425 426 /* Parse comma separated expression and return last result. */ 427 static void cp_expr_comma(CPState *cp, CPValue *k) 428 { 429 do { cp_expr_sub(cp, k, 0); } while (cp_opt(cp, ',')); 430 } 431 432 /* Parse sizeof/alignof operator. */ 433 static void cp_expr_sizeof(CPState *cp, CPValue *k, int wantsz) 434 { 435 CTSize sz; 436 CTInfo info; 437 if (cp_opt(cp, '(')) { 438 if (cp_istypedecl(cp)) 439 k->id = cp_decl_abstract(cp); 440 else 441 cp_expr_comma(cp, k); 442 cp_check(cp, ')'); 443 } else { 444 cp_expr_unary(cp, k); 445 } 446 info = lj_ctype_info(cp->cts, k->id, &sz); 447 if (wantsz) { 448 if (sz != CTSIZE_INVALID) 449 k->u32 = sz; 450 else if (k->id != CTID_A_CCHAR) /* Special case for sizeof("string"). */ 451 cp_err(cp, LJ_ERR_FFI_INVSIZE); 452 } else { 453 k->u32 = 1u << ctype_align(info); 454 } 455 k->id = CTID_UINT32; /* Really size_t. */ 456 } 457 458 /* Parse prefix operators. */ 459 static void cp_expr_prefix(CPState *cp, CPValue *k) 460 { 461 if (cp->tok == CTOK_INTEGER) { 462 *k = cp->val; cp_next(cp); 463 } else if (cp_opt(cp, '+')) { 464 cp_expr_unary(cp, k); /* Nothing to do (well, integer promotion). */ 465 } else if (cp_opt(cp, '-')) { 466 cp_expr_unary(cp, k); k->i32 = -k->i32; 467 } else if (cp_opt(cp, '~')) { 468 cp_expr_unary(cp, k); k->i32 = ~k->i32; 469 } else if (cp_opt(cp, '!')) { 470 cp_expr_unary(cp, k); k->i32 = !k->i32; k->id = CTID_INT32; 471 } else if (cp_opt(cp, '(')) { 472 if (cp_istypedecl(cp)) { /* Cast operator. */ 473 CTypeID id = cp_decl_abstract(cp); 474 cp_check(cp, ')'); 475 cp_expr_unary(cp, k); 476 k->id = id; /* No conversion performed. */ 477 } else { /* Sub-expression. */ 478 cp_expr_comma(cp, k); 479 cp_check(cp, ')'); 480 } 481 } else if (cp_opt(cp, '*')) { /* Indirection. */ 482 CType *ct; 483 cp_expr_unary(cp, k); 484 ct = lj_ctype_rawref(cp->cts, k->id); 485 if (!ctype_ispointer(ct->info)) 486 cp_err_badidx(cp, ct); 487 k->u32 = 0; k->id = ctype_cid(ct->info); 488 } else if (cp_opt(cp, '&')) { /* Address operator. */ 489 cp_expr_unary(cp, k); 490 k->id = lj_ctype_intern(cp->cts, CTINFO(CT_PTR, CTALIGN_PTR+k->id), 491 CTSIZE_PTR); 492 } else if (cp_opt(cp, CTOK_SIZEOF)) { 493 cp_expr_sizeof(cp, k, 1); 494 } else if (cp_opt(cp, CTOK_ALIGNOF)) { 495 cp_expr_sizeof(cp, k, 0); 496 } else if (cp->tok == CTOK_IDENT) { 497 if (ctype_type(cp->ct->info) == CT_CONSTVAL) { 498 k->u32 = cp->ct->size; k->id = ctype_cid(cp->ct->info); 499 } else if (ctype_type(cp->ct->info) == CT_EXTERN) { 500 k->u32 = cp->val.id; k->id = ctype_cid(cp->ct->info); 501 } else if (ctype_type(cp->ct->info) == CT_FUNC) { 502 k->u32 = cp->val.id; k->id = cp->val.id; 503 } else { 504 goto err_expr; 505 } 506 cp_next(cp); 507 } else if (cp->tok == CTOK_STRING) { 508 CTSize sz = cp->str->len; 509 while (cp_next(cp) == CTOK_STRING) 510 sz += cp->str->len; 511 k->u32 = sz + 1; 512 k->id = CTID_A_CCHAR; 513 } else { 514 err_expr: 515 cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL); 516 } 517 } 518 519 /* Parse postfix operators. */ 520 static void cp_expr_postfix(CPState *cp, CPValue *k) 521 { 522 for (;;) { 523 CType *ct; 524 if (cp_opt(cp, '[')) { /* Array/pointer index. */ 525 CPValue k2; 526 cp_expr_comma(cp, &k2); 527 ct = lj_ctype_rawref(cp->cts, k->id); 528 if (!ctype_ispointer(ct->info)) { 529 ct = lj_ctype_rawref(cp->cts, k2.id); 530 if (!ctype_ispointer(ct->info)) 531 cp_err_badidx(cp, ct); 532 } 533 cp_check(cp, ']'); 534 k->u32 = 0; 535 } else if (cp->tok == '.' || cp->tok == CTOK_DEREF) { /* Struct deref. */ 536 CTSize ofs; 537 CType *fct; 538 ct = lj_ctype_rawref(cp->cts, k->id); 539 if (cp->tok == CTOK_DEREF) { 540 if (!ctype_ispointer(ct->info)) 541 cp_err_badidx(cp, ct); 542 ct = lj_ctype_rawref(cp->cts, ctype_cid(ct->info)); 543 } 544 cp_next(cp); 545 if (cp->tok != CTOK_IDENT) cp_err_token(cp, CTOK_IDENT); 546 if (!ctype_isstruct(ct->info) || ct->size == CTSIZE_INVALID || 547 !(fct = lj_ctype_getfield(cp->cts, ct, cp->str, &ofs)) || 548 ctype_isbitfield(fct->info)) { 549 GCstr *s = lj_ctype_repr(cp->cts->L, ctype_typeid(cp->cts, ct), NULL); 550 cp_errmsg(cp, 0, LJ_ERR_FFI_BADMEMBER, strdata(s), strdata(cp->str)); 551 } 552 ct = fct; 553 k->u32 = ctype_isconstval(ct->info) ? ct->size : 0; 554 cp_next(cp); 555 } else { 556 return; 557 } 558 k->id = ctype_cid(ct->info); 559 } 560 } 561 562 /* Parse infix operators. */ 563 static void cp_expr_infix(CPState *cp, CPValue *k, int pri) 564 { 565 CPValue k2; 566 k2.u32 = 0; k2.id = 0; /* Silence the compiler. */ 567 for (;;) { 568 switch (pri) { 569 case 0: 570 if (cp_opt(cp, '?')) { 571 CPValue k3; 572 cp_expr_comma(cp, &k2); /* Right-associative. */ 573 cp_check(cp, ':'); 574 cp_expr_sub(cp, &k3, 0); 575 k->u32 = k->u32 ? k2.u32 : k3.u32; 576 k->id = k2.id > k3.id ? k2.id : k3.id; 577 continue; 578 } 579 case 1: 580 if (cp_opt(cp, CTOK_OROR)) { 581 cp_expr_sub(cp, &k2, 2); k->i32 = k->u32 || k2.u32; k->id = CTID_INT32; 582 continue; 583 } 584 case 2: 585 if (cp_opt(cp, CTOK_ANDAND)) { 586 cp_expr_sub(cp, &k2, 3); k->i32 = k->u32 && k2.u32; k->id = CTID_INT32; 587 continue; 588 } 589 case 3: 590 if (cp_opt(cp, '|')) { 591 cp_expr_sub(cp, &k2, 4); k->u32 = k->u32 | k2.u32; goto arith_result; 592 } 593 case 4: 594 if (cp_opt(cp, '^')) { 595 cp_expr_sub(cp, &k2, 5); k->u32 = k->u32 ^ k2.u32; goto arith_result; 596 } 597 case 5: 598 if (cp_opt(cp, '&')) { 599 cp_expr_sub(cp, &k2, 6); k->u32 = k->u32 & k2.u32; goto arith_result; 600 } 601 case 6: 602 if (cp_opt(cp, CTOK_EQ)) { 603 cp_expr_sub(cp, &k2, 7); k->i32 = k->u32 == k2.u32; k->id = CTID_INT32; 604 continue; 605 } else if (cp_opt(cp, CTOK_NE)) { 606 cp_expr_sub(cp, &k2, 7); k->i32 = k->u32 != k2.u32; k->id = CTID_INT32; 607 continue; 608 } 609 case 7: 610 if (cp_opt(cp, '<')) { 611 cp_expr_sub(cp, &k2, 8); 612 if (k->id == CTID_INT32 && k2.id == CTID_INT32) 613 k->i32 = k->i32 < k2.i32; 614 else 615 k->i32 = k->u32 < k2.u32; 616 k->id = CTID_INT32; 617 continue; 618 } else if (cp_opt(cp, '>')) { 619 cp_expr_sub(cp, &k2, 8); 620 if (k->id == CTID_INT32 && k2.id == CTID_INT32) 621 k->i32 = k->i32 > k2.i32; 622 else 623 k->i32 = k->u32 > k2.u32; 624 k->id = CTID_INT32; 625 continue; 626 } else if (cp_opt(cp, CTOK_LE)) { 627 cp_expr_sub(cp, &k2, 8); 628 if (k->id == CTID_INT32 && k2.id == CTID_INT32) 629 k->i32 = k->i32 <= k2.i32; 630 else 631 k->i32 = k->u32 <= k2.u32; 632 k->id = CTID_INT32; 633 continue; 634 } else if (cp_opt(cp, CTOK_GE)) { 635 cp_expr_sub(cp, &k2, 8); 636 if (k->id == CTID_INT32 && k2.id == CTID_INT32) 637 k->i32 = k->i32 >= k2.i32; 638 else 639 k->i32 = k->u32 >= k2.u32; 640 k->id = CTID_INT32; 641 continue; 642 } 643 case 8: 644 if (cp_opt(cp, CTOK_SHL)) { 645 cp_expr_sub(cp, &k2, 9); k->u32 = k->u32 << k2.u32; 646 continue; 647 } else if (cp_opt(cp, CTOK_SHR)) { 648 cp_expr_sub(cp, &k2, 9); 649 if (k->id == CTID_INT32) 650 k->i32 = k->i32 >> k2.i32; 651 else 652 k->u32 = k->u32 >> k2.u32; 653 continue; 654 } 655 case 9: 656 if (cp_opt(cp, '+')) { 657 cp_expr_sub(cp, &k2, 10); k->u32 = k->u32 + k2.u32; 658 arith_result: 659 if (k2.id > k->id) k->id = k2.id; /* Trivial promotion to unsigned. */ 660 continue; 661 } else if (cp_opt(cp, '-')) { 662 cp_expr_sub(cp, &k2, 10); k->u32 = k->u32 - k2.u32; goto arith_result; 663 } 664 case 10: 665 if (cp_opt(cp, '*')) { 666 cp_expr_unary(cp, &k2); k->u32 = k->u32 * k2.u32; goto arith_result; 667 } else if (cp_opt(cp, '/')) { 668 cp_expr_unary(cp, &k2); 669 if (k2.id > k->id) k->id = k2.id; /* Trivial promotion to unsigned. */ 670 if (k2.u32 == 0 || 671 (k->id == CTID_INT32 && k->u32 == 0x80000000u && k2.i32 == -1)) 672 cp_err(cp, LJ_ERR_BADVAL); 673 if (k->id == CTID_INT32) 674 k->i32 = k->i32 / k2.i32; 675 else 676 k->u32 = k->u32 / k2.u32; 677 continue; 678 } else if (cp_opt(cp, '%')) { 679 cp_expr_unary(cp, &k2); 680 if (k2.id > k->id) k->id = k2.id; /* Trivial promotion to unsigned. */ 681 if (k2.u32 == 0 || 682 (k->id == CTID_INT32 && k->u32 == 0x80000000u && k2.i32 == -1)) 683 cp_err(cp, LJ_ERR_BADVAL); 684 if (k->id == CTID_INT32) 685 k->i32 = k->i32 % k2.i32; 686 else 687 k->u32 = k->u32 % k2.u32; 688 continue; 689 } 690 default: 691 return; 692 } 693 } 694 } 695 696 /* Parse and evaluate unary expression. */ 697 static void cp_expr_unary(CPState *cp, CPValue *k) 698 { 699 if (++cp->depth > CPARSE_MAX_DECLDEPTH) cp_err(cp, LJ_ERR_XLEVELS); 700 cp_expr_prefix(cp, k); 701 cp_expr_postfix(cp, k); 702 cp->depth--; 703 } 704 705 /* Parse and evaluate sub-expression. */ 706 static void cp_expr_sub(CPState *cp, CPValue *k, int pri) 707 { 708 cp_expr_unary(cp, k); 709 cp_expr_infix(cp, k, pri); 710 } 711 712 /* Parse constant integer expression. */ 713 static void cp_expr_kint(CPState *cp, CPValue *k) 714 { 715 CType *ct; 716 cp_expr_sub(cp, k, 0); 717 ct = ctype_raw(cp->cts, k->id); 718 if (!ctype_isinteger(ct->info)) cp_err(cp, LJ_ERR_BADVAL); 719 } 720 721 /* Parse (non-negative) size expression. */ 722 static CTSize cp_expr_ksize(CPState *cp) 723 { 724 CPValue k; 725 cp_expr_kint(cp, &k); 726 if (k.u32 >= 0x80000000u) cp_err(cp, LJ_ERR_FFI_INVSIZE); 727 return k.u32; 728 } 729 730 /* -- Type declaration stack management ----------------------------------- */ 731 732 /* Add declaration element behind the insertion position. */ 733 static CPDeclIdx cp_add(CPDecl *decl, CTInfo info, CTSize size) 734 { 735 CPDeclIdx top = decl->top; 736 if (top >= CPARSE_MAX_DECLSTACK) cp_err(decl->cp, LJ_ERR_XLEVELS); 737 decl->stack[top].info = info; 738 decl->stack[top].size = size; 739 decl->stack[top].sib = 0; 740 setgcrefnull(decl->stack[top].name); 741 decl->stack[top].next = decl->stack[decl->pos].next; 742 decl->stack[decl->pos].next = (CTypeID1)top; 743 decl->top = top+1; 744 return top; 745 } 746 747 /* Push declaration element before the insertion position. */ 748 static CPDeclIdx cp_push(CPDecl *decl, CTInfo info, CTSize size) 749 { 750 return (decl->pos = cp_add(decl, info, size)); 751 } 752 753 /* Push or merge attributes. */ 754 static void cp_push_attributes(CPDecl *decl) 755 { 756 CType *ct = &decl->stack[decl->pos]; 757 if (ctype_isfunc(ct->info)) { /* Ok to modify in-place. */ 758 #if LJ_TARGET_X86 759 if ((decl->fattr & CTFP_CCONV)) 760 ct->info = (ct->info & (CTMASK_NUM|CTF_VARARG|CTMASK_CID)) + 761 (decl->fattr & ~CTMASK_CID); 762 #endif 763 } else { 764 if ((decl->attr & CTFP_ALIGNED) && !(decl->mode & CPARSE_MODE_FIELD)) 765 cp_push(decl, CTINFO(CT_ATTRIB, CTATTRIB(CTA_ALIGN)), 766 ctype_align(decl->attr)); 767 } 768 } 769 770 /* Push unrolled type to declaration stack and merge qualifiers. */ 771 static void cp_push_type(CPDecl *decl, CTypeID id) 772 { 773 CType *ct = ctype_get(decl->cp->cts, id); 774 CTInfo info = ct->info; 775 CTSize size = ct->size; 776 switch (ctype_type(info)) { 777 case CT_STRUCT: case CT_ENUM: 778 cp_push(decl, CTINFO(CT_TYPEDEF, id), 0); /* Don't copy unique types. */ 779 if ((decl->attr & CTF_QUAL)) { /* Push unmerged qualifiers. */ 780 cp_push(decl, CTINFO(CT_ATTRIB, CTATTRIB(CTA_QUAL)), 781 (decl->attr & CTF_QUAL)); 782 decl->attr &= ~CTF_QUAL; 783 } 784 break; 785 case CT_ATTRIB: 786 if (ctype_isxattrib(info, CTA_QUAL)) 787 decl->attr &= ~size; /* Remove redundant qualifiers. */ 788 cp_push_type(decl, ctype_cid(info)); /* Unroll. */ 789 cp_push(decl, info & ~CTMASK_CID, size); /* Copy type. */ 790 break; 791 case CT_ARRAY: 792 if ((ct->info & (CTF_VECTOR|CTF_COMPLEX))) { 793 info |= (decl->attr & CTF_QUAL); 794 decl->attr &= ~CTF_QUAL; 795 } 796 cp_push_type(decl, ctype_cid(info)); /* Unroll. */ 797 cp_push(decl, info & ~CTMASK_CID, size); /* Copy type. */ 798 decl->stack[decl->pos].sib = 1; /* Mark as already checked and sized. */ 799 /* Note: this is not copied to the ct->sib in the C type table. */ 800 break; 801 case CT_FUNC: 802 /* Copy type, link parameters (shared). */ 803 decl->stack[cp_push(decl, info, size)].sib = ct->sib; 804 break; 805 default: 806 /* Copy type, merge common qualifiers. */ 807 cp_push(decl, info|(decl->attr & CTF_QUAL), size); 808 decl->attr &= ~CTF_QUAL; 809 break; 810 } 811 } 812 813 /* Consume the declaration element chain and intern the C type. */ 814 static CTypeID cp_decl_intern(CPState *cp, CPDecl *decl) 815 { 816 CTypeID id = 0; 817 CPDeclIdx idx = 0; 818 CTSize csize = CTSIZE_INVALID; 819 CTSize cinfo = 0; 820 do { 821 CType *ct = &decl->stack[idx]; 822 CTInfo info = ct->info; 823 CTInfo size = ct->size; 824 /* The cid is already part of info for copies of pointers/functions. */ 825 idx = ct->next; 826 if (ctype_istypedef(info)) { 827 lua_assert(id == 0); 828 id = ctype_cid(info); 829 /* Always refetch info/size, since struct/enum may have been completed. */ 830 cinfo = ctype_get(cp->cts, id)->info; 831 csize = ctype_get(cp->cts, id)->size; 832 lua_assert(ctype_isstruct(cinfo) || ctype_isenum(cinfo)); 833 } else if (ctype_isfunc(info)) { /* Intern function. */ 834 CType *fct; 835 CTypeID fid; 836 CTypeID sib; 837 if (id) { 838 CType *refct = ctype_raw(cp->cts, id); 839 /* Reject function or refarray return types. */ 840 if (ctype_isfunc(refct->info) || ctype_isrefarray(refct->info)) 841 cp_err(cp, LJ_ERR_FFI_INVTYPE); 842 } 843 /* No intervening attributes allowed, skip forward. */ 844 while (idx) { 845 CType *ctn = &decl->stack[idx]; 846 if (!ctype_isattrib(ctn->info)) break; 847 idx = ctn->next; /* Skip attribute. */ 848 } 849 sib = ct->sib; /* Next line may reallocate the C type table. */ 850 fid = lj_ctype_new(cp->cts, &fct); 851 csize = CTSIZE_INVALID; 852 fct->info = cinfo = info + id; 853 fct->size = size; 854 fct->sib = sib; 855 id = fid; 856 } else if (ctype_isattrib(info)) { 857 if (ctype_isxattrib(info, CTA_QUAL)) 858 cinfo |= size; 859 else if (ctype_isxattrib(info, CTA_ALIGN)) 860 CTF_INSERT(cinfo, ALIGN, size); 861 id = lj_ctype_intern(cp->cts, info+id, size); 862 /* Inherit csize/cinfo from original type. */ 863 } else { 864 if (ctype_isnum(info)) { /* Handle mode/vector-size attributes. */ 865 lua_assert(id == 0); 866 if (!(info & CTF_BOOL)) { 867 CTSize msize = ctype_msizeP(decl->attr); 868 CTSize vsize = ctype_vsizeP(decl->attr); 869 if (msize && (!(info & CTF_FP) || (msize == 4 || msize == 8))) { 870 CTSize malign = lj_fls(msize); 871 if (malign > 4) malign = 4; /* Limit alignment. */ 872 CTF_INSERT(info, ALIGN, malign); 873 size = msize; /* Override size via mode. */ 874 } 875 if (vsize) { /* Vector size set? */ 876 CTSize esize = lj_fls(size); 877 if (vsize >= esize) { 878 /* Intern the element type first. */ 879 id = lj_ctype_intern(cp->cts, info, size); 880 /* Then create a vector (array) with vsize alignment. */ 881 size = (1u << vsize); 882 if (vsize > 4) vsize = 4; /* Limit alignment. */ 883 if (ctype_align(info) > vsize) vsize = ctype_align(info); 884 info = CTINFO(CT_ARRAY, (info & CTF_QUAL) + CTF_VECTOR + 885 CTALIGN(vsize)); 886 } 887 } 888 } 889 } else if (ctype_isptr(info)) { 890 /* Reject pointer/ref to ref. */ 891 if (id && ctype_isref(ctype_raw(cp->cts, id)->info)) 892 cp_err(cp, LJ_ERR_FFI_INVTYPE); 893 if (ctype_isref(info)) { 894 info &= ~CTF_VOLATILE; /* Refs are always const, never volatile. */ 895 /* No intervening attributes allowed, skip forward. */ 896 while (idx) { 897 CType *ctn = &decl->stack[idx]; 898 if (!ctype_isattrib(ctn->info)) break; 899 idx = ctn->next; /* Skip attribute. */ 900 } 901 } 902 } else if (ctype_isarray(info)) { /* Check for valid array size etc. */ 903 if (ct->sib == 0) { /* Only check/size arrays not copied by unroll. */ 904 if (ctype_isref(cinfo)) /* Reject arrays of refs. */ 905 cp_err(cp, LJ_ERR_FFI_INVTYPE); 906 /* Reject VLS or unknown-sized types. */ 907 if (ctype_isvltype(cinfo) || csize == CTSIZE_INVALID) 908 cp_err(cp, LJ_ERR_FFI_INVSIZE); 909 /* a[] and a[?] keep their invalid size. */ 910 if (size != CTSIZE_INVALID) { 911 uint64_t xsz = (uint64_t)size * csize; 912 if (xsz >= 0x80000000u) cp_err(cp, LJ_ERR_FFI_INVSIZE); 913 size = (CTSize)xsz; 914 } 915 } 916 if ((cinfo & CTF_ALIGN) > (info & CTF_ALIGN)) /* Find max. align. */ 917 info = (info & ~CTF_ALIGN) | (cinfo & CTF_ALIGN); 918 info |= (cinfo & CTF_QUAL); /* Inherit qual. */ 919 } else { 920 lua_assert(ctype_isvoid(info)); 921 } 922 csize = size; 923 cinfo = info+id; 924 id = lj_ctype_intern(cp->cts, info+id, size); 925 } 926 } while (idx); 927 return id; 928 } 929 930 /* -- C declaration parser ------------------------------------------------ */ 931 932 #define H_(le, be) LJ_ENDIAN_SELECT(0x##le, 0x##be) 933 934 /* Reset declaration state to declaration specifier. */ 935 static void cp_decl_reset(CPDecl *decl) 936 { 937 decl->pos = decl->specpos; 938 decl->top = decl->specpos+1; 939 decl->stack[decl->specpos].next = 0; 940 decl->attr = decl->specattr; 941 decl->fattr = decl->specfattr; 942 decl->name = NULL; 943 decl->redir = NULL; 944 } 945 946 /* Parse constant initializer. */ 947 /* NYI: FP constants and strings as initializers. */ 948 static CTypeID cp_decl_constinit(CPState *cp, CType **ctp, CTypeID ctypeid) 949 { 950 CType *ctt = ctype_get(cp->cts, ctypeid); 951 CTInfo info; 952 CTSize size; 953 CPValue k; 954 CTypeID constid; 955 while (ctype_isattrib(ctt->info)) { /* Skip attributes. */ 956 ctypeid = ctype_cid(ctt->info); /* Update ID, too. */ 957 ctt = ctype_get(cp->cts, ctypeid); 958 } 959 info = ctt->info; 960 size = ctt->size; 961 if (!ctype_isinteger(info) || !(info & CTF_CONST) || size > 4) 962 cp_err(cp, LJ_ERR_FFI_INVTYPE); 963 cp_check(cp, '='); 964 cp_expr_sub(cp, &k, 0); 965 constid = lj_ctype_new(cp->cts, ctp); 966 (*ctp)->info = CTINFO(CT_CONSTVAL, CTF_CONST|ctypeid); 967 k.u32 <<= 8*(4-size); 968 if ((info & CTF_UNSIGNED)) 969 k.u32 >>= 8*(4-size); 970 else 971 k.u32 = (uint32_t)((int32_t)k.u32 >> 8*(4-size)); 972 (*ctp)->size = k.u32; 973 return constid; 974 } 975 976 /* Parse size in parentheses as part of attribute. */ 977 static CTSize cp_decl_sizeattr(CPState *cp) 978 { 979 CTSize sz; 980 uint32_t oldtmask = cp->tmask; 981 cp->tmask = CPNS_DEFAULT; /* Required for expression evaluator. */ 982 cp_check(cp, '('); 983 sz = cp_expr_ksize(cp); 984 cp->tmask = oldtmask; 985 cp_check(cp, ')'); 986 return sz; 987 } 988 989 /* Parse alignment attribute. */ 990 static void cp_decl_align(CPState *cp, CPDecl *decl) 991 { 992 CTSize al = 4; /* Unspecified alignment is 16 bytes. */ 993 if (cp->tok == '(') { 994 al = cp_decl_sizeattr(cp); 995 al = al ? lj_fls(al) : 0; 996 } 997 CTF_INSERT(decl->attr, ALIGN, al); 998 decl->attr |= CTFP_ALIGNED; 999 } 1000 1001 /* Parse GCC asm("name") redirect. */ 1002 static void cp_decl_asm(CPState *cp, CPDecl *decl) 1003 { 1004 UNUSED(decl); 1005 cp_next(cp); 1006 cp_check(cp, '('); 1007 if (cp->tok == CTOK_STRING) { 1008 GCstr *str = cp->str; 1009 while (cp_next(cp) == CTOK_STRING) { 1010 lj_strfmt_pushf(cp->L, "%s%s", strdata(str), strdata(cp->str)); 1011 cp->L->top--; 1012 str = strV(cp->L->top); 1013 } 1014 decl->redir = str; 1015 } 1016 cp_check(cp, ')'); 1017 } 1018 1019 /* Parse GCC __attribute__((mode(...))). */ 1020 static void cp_decl_mode(CPState *cp, CPDecl *decl) 1021 { 1022 cp_check(cp, '('); 1023 if (cp->tok == CTOK_IDENT) { 1024 const char *s = strdata(cp->str); 1025 CTSize sz = 0, vlen = 0; 1026 if (s[0] == '_' && s[1] == '_') s += 2; 1027 if (*s == 'V') { 1028 s++; 1029 vlen = *s++ - '0'; 1030 if (*s >= '0' && *s <= '9') 1031 vlen = vlen*10 + (*s++ - '0'); 1032 } 1033 switch (*s++) { 1034 case 'Q': sz = 1; break; 1035 case 'H': sz = 2; break; 1036 case 'S': sz = 4; break; 1037 case 'D': sz = 8; break; 1038 case 'T': sz = 16; break; 1039 case 'O': sz = 32; break; 1040 default: goto bad_size; 1041 } 1042 if (*s == 'I' || *s == 'F') { 1043 CTF_INSERT(decl->attr, MSIZEP, sz); 1044 if (vlen) CTF_INSERT(decl->attr, VSIZEP, lj_fls(vlen*sz)); 1045 } 1046 bad_size: 1047 cp_next(cp); 1048 } 1049 cp_check(cp, ')'); 1050 } 1051 1052 /* Parse GCC __attribute__((...)). */ 1053 static void cp_decl_gccattribute(CPState *cp, CPDecl *decl) 1054 { 1055 cp_next(cp); 1056 cp_check(cp, '('); 1057 cp_check(cp, '('); 1058 while (cp->tok != ')') { 1059 if (cp->tok == CTOK_IDENT) { 1060 GCstr *attrstr = cp->str; 1061 cp_next(cp); 1062 switch (attrstr->hash) { 1063 case H_(64a9208e,8ce14319): case H_(8e6331b2,95a282af): /* aligned */ 1064 cp_decl_align(cp, decl); 1065 break; 1066 case H_(42eb47de,f0ede26c): case H_(29f48a09,cf383e0c): /* packed */ 1067 decl->attr |= CTFP_PACKED; 1068 break; 1069 case H_(0a84eef6,8dfab04c): case H_(995cf92c,d5696591): /* mode */ 1070 cp_decl_mode(cp, decl); 1071 break; 1072 case H_(0ab31997,2d5213fa): case H_(bf875611,200e9990): /* vector_size */ 1073 { 1074 CTSize vsize = cp_decl_sizeattr(cp); 1075 if (vsize) CTF_INSERT(decl->attr, VSIZEP, lj_fls(vsize)); 1076 } 1077 break; 1078 #if LJ_TARGET_X86 1079 case H_(5ad22db8,c689b848): case H_(439150fa,65ea78cb): /* regparm */ 1080 CTF_INSERT(decl->fattr, REGPARM, cp_decl_sizeattr(cp)); 1081 decl->fattr |= CTFP_CCONV; 1082 break; 1083 case H_(18fc0b98,7ff4c074): case H_(4e62abed,0a747424): /* cdecl */ 1084 CTF_INSERT(decl->fattr, CCONV, CTCC_CDECL); 1085 decl->fattr |= CTFP_CCONV; 1086 break; 1087 case H_(72b2e41b,494c5a44): case H_(f2356d59,f25fc9bd): /* thiscall */ 1088 CTF_INSERT(decl->fattr, CCONV, CTCC_THISCALL); 1089 decl->fattr |= CTFP_CCONV; 1090 break; 1091 case H_(0d0ffc42,ab746f88): case H_(21c54ba1,7f0ca7e3): /* fastcall */ 1092 CTF_INSERT(decl->fattr, CCONV, CTCC_FASTCALL); 1093 decl->fattr |= CTFP_CCONV; 1094 break; 1095 case H_(ef76b040,9412e06a): case H_(de56697b,c750e6e1): /* stdcall */ 1096 CTF_INSERT(decl->fattr, CCONV, CTCC_STDCALL); 1097 decl->fattr |= CTFP_CCONV; 1098 break; 1099 case H_(ea78b622,f234bd8e): case H_(252ffb06,8d50f34b): /* sseregparm */ 1100 decl->fattr |= CTF_SSEREGPARM; 1101 decl->fattr |= CTFP_CCONV; 1102 break; 1103 #endif 1104 default: /* Skip all other attributes. */ 1105 goto skip_attr; 1106 } 1107 } else if (cp->tok >= CTOK_FIRSTDECL) { /* For __attribute((const)) etc. */ 1108 cp_next(cp); 1109 skip_attr: 1110 if (cp_opt(cp, '(')) { 1111 while (cp->tok != ')' && cp->tok != CTOK_EOF) cp_next(cp); 1112 cp_check(cp, ')'); 1113 } 1114 } else { 1115 break; 1116 } 1117 if (!cp_opt(cp, ',')) break; 1118 } 1119 cp_check(cp, ')'); 1120 cp_check(cp, ')'); 1121 } 1122 1123 /* Parse MSVC __declspec(...). */ 1124 static void cp_decl_msvcattribute(CPState *cp, CPDecl *decl) 1125 { 1126 cp_next(cp); 1127 cp_check(cp, '('); 1128 while (cp->tok == CTOK_IDENT) { 1129 GCstr *attrstr = cp->str; 1130 cp_next(cp); 1131 switch (attrstr->hash) { 1132 case H_(bc2395fa,98f267f8): /* align */ 1133 cp_decl_align(cp, decl); 1134 break; 1135 default: /* Ignore all other attributes. */ 1136 if (cp_opt(cp, '(')) { 1137 while (cp->tok != ')' && cp->tok != CTOK_EOF) cp_next(cp); 1138 cp_check(cp, ')'); 1139 } 1140 break; 1141 } 1142 } 1143 cp_check(cp, ')'); 1144 } 1145 1146 /* Parse declaration attributes (and common qualifiers). */ 1147 static void cp_decl_attributes(CPState *cp, CPDecl *decl) 1148 { 1149 for (;;) { 1150 switch (cp->tok) { 1151 case CTOK_CONST: decl->attr |= CTF_CONST; break; 1152 case CTOK_VOLATILE: decl->attr |= CTF_VOLATILE; break; 1153 case CTOK_RESTRICT: break; /* Ignore. */ 1154 case CTOK_EXTENSION: break; /* Ignore. */ 1155 case CTOK_ATTRIBUTE: cp_decl_gccattribute(cp, decl); continue; 1156 case CTOK_ASM: cp_decl_asm(cp, decl); continue; 1157 case CTOK_DECLSPEC: cp_decl_msvcattribute(cp, decl); continue; 1158 case CTOK_CCDECL: 1159 #if LJ_TARGET_X86 1160 CTF_INSERT(decl->fattr, CCONV, cp->ct->size); 1161 decl->fattr |= CTFP_CCONV; 1162 #endif 1163 break; 1164 case CTOK_PTRSZ: 1165 #if LJ_64 1166 CTF_INSERT(decl->attr, MSIZEP, cp->ct->size); 1167 #endif 1168 break; 1169 default: return; 1170 } 1171 cp_next(cp); 1172 } 1173 } 1174 1175 /* Parse struct/union/enum name. */ 1176 static CTypeID cp_struct_name(CPState *cp, CPDecl *sdecl, CTInfo info) 1177 { 1178 CTypeID sid; 1179 CType *ct; 1180 cp->tmask = CPNS_STRUCT; 1181 cp_next(cp); 1182 cp_decl_attributes(cp, sdecl); 1183 cp->tmask = CPNS_DEFAULT; 1184 if (cp->tok != '{') { 1185 if (cp->tok != CTOK_IDENT) cp_err_token(cp, CTOK_IDENT); 1186 if (cp->val.id) { /* Name of existing struct/union/enum. */ 1187 sid = cp->val.id; 1188 ct = cp->ct; 1189 if ((ct->info ^ info) & (CTMASK_NUM|CTF_UNION)) /* Wrong type. */ 1190 cp_errmsg(cp, 0, LJ_ERR_FFI_REDEF, strdata(gco2str(gcref(ct->name)))); 1191 } else { /* Create named, incomplete struct/union/enum. */ 1192 if ((cp->mode & CPARSE_MODE_NOIMPLICIT)) 1193 cp_errmsg(cp, 0, LJ_ERR_FFI_BADTAG, strdata(cp->str)); 1194 sid = lj_ctype_new(cp->cts, &ct); 1195 ct->info = info; 1196 ct->size = CTSIZE_INVALID; 1197 ctype_setname(ct, cp->str); 1198 lj_ctype_addname(cp->cts, ct, sid); 1199 } 1200 cp_next(cp); 1201 } else { /* Create anonymous, incomplete struct/union/enum. */ 1202 sid = lj_ctype_new(cp->cts, &ct); 1203 ct->info = info; 1204 ct->size = CTSIZE_INVALID; 1205 } 1206 if (cp->tok == '{') { 1207 if (ct->size != CTSIZE_INVALID || ct->sib) 1208 cp_errmsg(cp, 0, LJ_ERR_FFI_REDEF, strdata(gco2str(gcref(ct->name)))); 1209 ct->sib = 1; /* Indicate the type is currently being defined. */ 1210 } 1211 return sid; 1212 } 1213 1214 /* Determine field alignment. */ 1215 static CTSize cp_field_align(CPState *cp, CType *ct, CTInfo info) 1216 { 1217 CTSize align = ctype_align(info); 1218 UNUSED(cp); UNUSED(ct); 1219 #if (LJ_TARGET_X86 && (!LJ_ABI_WIN || LJ_TARGET_POSIX)) || (LJ_TARGET_ARM && __APPLE__) 1220 /* The SYSV i386 and iOS ABIs limit alignment of non-vector fields to 2^2. */ 1221 if (align > 2 && !(info & CTFP_ALIGNED)) { 1222 if (ctype_isarray(info) && !(info & CTF_VECTOR)) { 1223 do { 1224 ct = ctype_rawchild(cp->cts, ct); 1225 info = ct->info; 1226 } while (ctype_isarray(info) && !(info & CTF_VECTOR)); 1227 } 1228 if (ctype_isnum(info) || ctype_isenum(info)) 1229 align = 2; 1230 } 1231 #endif 1232 return align; 1233 } 1234 1235 /* Layout struct/union fields. */ 1236 static void cp_struct_layout(CPState *cp, CTypeID sid, CTInfo sattr) 1237 { 1238 CTSize bofs = 0, bmaxofs = 0; /* Bit offset and max. bit offset. */ 1239 CTSize maxalign = ctype_align(sattr); 1240 CType *sct = ctype_get(cp->cts, sid); 1241 CTInfo sinfo = sct->info; 1242 CTypeID fieldid = sct->sib; 1243 while (fieldid) { 1244 CType *ct = ctype_get(cp->cts, fieldid); 1245 CTInfo attr = ct->size; /* Field declaration attributes (temp.). */ 1246 1247 if (ctype_isfield(ct->info) || 1248 (ctype_isxattrib(ct->info, CTA_SUBTYPE) && attr)) { 1249 CTSize align, amask; /* Alignment (pow2) and alignment mask (bits). */ 1250 CTSize sz; 1251 CTInfo info = lj_ctype_info(cp->cts, ctype_cid(ct->info), &sz); 1252 CTSize bsz, csz = 8*sz; /* Field size and container size (in bits). */ 1253 sinfo |= (info & (CTF_QUAL|CTF_VLA)); /* Merge pseudo-qualifiers. */ 1254 1255 /* Check for size overflow and determine alignment. */ 1256 if (sz >= 0x20000000u || bofs + csz < bofs || (info & CTF_VLA)) { 1257 if (!(sz == CTSIZE_INVALID && ctype_isarray(info) && 1258 !(sinfo & CTF_UNION))) 1259 cp_err(cp, LJ_ERR_FFI_INVSIZE); 1260 csz = sz = 0; /* Treat a[] and a[?] as zero-sized. */ 1261 } 1262 align = cp_field_align(cp, ct, info); 1263 if (((attr|sattr) & CTFP_PACKED) || 1264 ((attr & CTFP_ALIGNED) && ctype_align(attr) > align)) 1265 align = ctype_align(attr); 1266 if (cp->packstack[cp->curpack] < align) 1267 align = cp->packstack[cp->curpack]; 1268 if (align > maxalign) maxalign = align; 1269 amask = (8u << align) - 1; 1270 1271 bsz = ctype_bitcsz(ct->info); /* Bitfield size (temp.). */ 1272 if (bsz == CTBSZ_FIELD || !ctype_isfield(ct->info)) { 1273 bsz = csz; /* Regular fields or subtypes always fill the container. */ 1274 bofs = (bofs + amask) & ~amask; /* Start new aligned field. */ 1275 ct->size = (bofs >> 3); /* Store field offset. */ 1276 } else { /* Bitfield. */ 1277 if (bsz == 0 || (attr & CTFP_ALIGNED) || 1278 (!((attr|sattr) & CTFP_PACKED) && (bofs & amask) + bsz > csz)) 1279 bofs = (bofs + amask) & ~amask; /* Start new aligned field. */ 1280 1281 /* Prefer regular field over bitfield. */ 1282 if (bsz == csz && (bofs & amask) == 0) { 1283 ct->info = CTINFO(CT_FIELD, ctype_cid(ct->info)); 1284 ct->size = (bofs >> 3); /* Store field offset. */ 1285 } else { 1286 ct->info = CTINFO(CT_BITFIELD, 1287 (info & (CTF_QUAL|CTF_UNSIGNED|CTF_BOOL)) + 1288 (csz << (CTSHIFT_BITCSZ-3)) + (bsz << CTSHIFT_BITBSZ)); 1289 #if LJ_BE 1290 ct->info += ((csz - (bofs & (csz-1)) - bsz) << CTSHIFT_BITPOS); 1291 #else 1292 ct->info += ((bofs & (csz-1)) << CTSHIFT_BITPOS); 1293 #endif 1294 ct->size = ((bofs & ~(csz-1)) >> 3); /* Store container offset. */ 1295 } 1296 } 1297 1298 /* Determine next offset or max. offset. */ 1299 if ((sinfo & CTF_UNION)) { 1300 if (bsz > bmaxofs) bmaxofs = bsz; 1301 } else { 1302 bofs += bsz; 1303 } 1304 } /* All other fields in the chain are already set up. */ 1305 1306 fieldid = ct->sib; 1307 } 1308 1309 /* Complete struct/union. */ 1310 sct->info = sinfo + CTALIGN(maxalign); 1311 bofs = (sinfo & CTF_UNION) ? bmaxofs : bofs; 1312 maxalign = (8u << maxalign) - 1; 1313 sct->size = (((bofs + maxalign) & ~maxalign) >> 3); 1314 } 1315 1316 /* Parse struct/union declaration. */ 1317 static CTypeID cp_decl_struct(CPState *cp, CPDecl *sdecl, CTInfo sinfo) 1318 { 1319 CTypeID sid = cp_struct_name(cp, sdecl, sinfo); 1320 if (cp_opt(cp, '{')) { /* Struct/union definition. */ 1321 CTypeID lastid = sid; 1322 int lastdecl = 0; 1323 while (cp->tok != '}') { 1324 CPDecl decl; 1325 CPscl scl = cp_decl_spec(cp, &decl, CDF_STATIC); 1326 decl.mode = scl ? CPARSE_MODE_DIRECT : 1327 CPARSE_MODE_DIRECT|CPARSE_MODE_ABSTRACT|CPARSE_MODE_FIELD; 1328 1329 for (;;) { 1330 CTypeID ctypeid; 1331 1332 if (lastdecl) cp_err_token(cp, '}'); 1333 1334 /* Parse field declarator. */ 1335 decl.bits = CTSIZE_INVALID; 1336 cp_declarator(cp, &decl); 1337 ctypeid = cp_decl_intern(cp, &decl); 1338 1339 if ((scl & CDF_STATIC)) { /* Static constant in struct namespace. */ 1340 CType *ct; 1341 CTypeID fieldid = cp_decl_constinit(cp, &ct, ctypeid); 1342 ctype_get(cp->cts, lastid)->sib = fieldid; 1343 lastid = fieldid; 1344 ctype_setname(ct, decl.name); 1345 } else { 1346 CTSize bsz = CTBSZ_FIELD; /* Temp. for layout phase. */ 1347 CType *ct; 1348 CTypeID fieldid = lj_ctype_new(cp->cts, &ct); /* Do this first. */ 1349 CType *tct = ctype_raw(cp->cts, ctypeid); 1350 1351 if (decl.bits == CTSIZE_INVALID) { /* Regular field. */ 1352 if (ctype_isarray(tct->info) && tct->size == CTSIZE_INVALID) 1353 lastdecl = 1; /* a[] or a[?] must be the last declared field. */ 1354 1355 /* Accept transparent struct/union/enum. */ 1356 if (!decl.name) { 1357 if (!((ctype_isstruct(tct->info) && !(tct->info & CTF_VLA)) || 1358 ctype_isenum(tct->info))) 1359 cp_err_token(cp, CTOK_IDENT); 1360 ct->info = CTINFO(CT_ATTRIB, CTATTRIB(CTA_SUBTYPE) + ctypeid); 1361 ct->size = ctype_isstruct(tct->info) ? 1362 (decl.attr|0x80000000u) : 0; /* For layout phase. */ 1363 goto add_field; 1364 } 1365 } else { /* Bitfield. */ 1366 bsz = decl.bits; 1367 if (!ctype_isinteger_or_bool(tct->info) || 1368 (bsz == 0 && decl.name) || 8*tct->size > CTBSZ_MAX || 1369 bsz > ((tct->info & CTF_BOOL) ? 1 : 8*tct->size)) 1370 cp_errmsg(cp, ':', LJ_ERR_BADVAL); 1371 } 1372 1373 /* Create temporary field for layout phase. */ 1374 ct->info = CTINFO(CT_FIELD, ctypeid + (bsz << CTSHIFT_BITCSZ)); 1375 ct->size = decl.attr; 1376 if (decl.name) ctype_setname(ct, decl.name); 1377 1378 add_field: 1379 ctype_get(cp->cts, lastid)->sib = fieldid; 1380 lastid = fieldid; 1381 } 1382 if (!cp_opt(cp, ',')) break; 1383 cp_decl_reset(&decl); 1384 } 1385 cp_check(cp, ';'); 1386 } 1387 cp_check(cp, '}'); 1388 ctype_get(cp->cts, lastid)->sib = 0; /* Drop sib = 1 for empty structs. */ 1389 cp_decl_attributes(cp, sdecl); /* Layout phase needs postfix attributes. */ 1390 cp_struct_layout(cp, sid, sdecl->attr); 1391 } 1392 return sid; 1393 } 1394 1395 /* Parse enum declaration. */ 1396 static CTypeID cp_decl_enum(CPState *cp, CPDecl *sdecl) 1397 { 1398 CTypeID eid = cp_struct_name(cp, sdecl, CTINFO(CT_ENUM, CTID_VOID)); 1399 CTInfo einfo = CTINFO(CT_ENUM, CTALIGN(2) + CTID_UINT32); 1400 CTSize esize = 4; /* Only 32 bit enums are supported. */ 1401 if (cp_opt(cp, '{')) { /* Enum definition. */ 1402 CPValue k; 1403 CTypeID lastid = eid; 1404 k.u32 = 0; 1405 k.id = CTID_INT32; 1406 do { 1407 GCstr *name = cp->str; 1408 if (cp->tok != CTOK_IDENT) cp_err_token(cp, CTOK_IDENT); 1409 if (cp->val.id) cp_errmsg(cp, 0, LJ_ERR_FFI_REDEF, strdata(name)); 1410 cp_next(cp); 1411 if (cp_opt(cp, '=')) { 1412 cp_expr_kint(cp, &k); 1413 if (k.id == CTID_UINT32) { 1414 /* C99 says that enum constants are always (signed) integers. 1415 ** But since unsigned constants like 0x80000000 are quite common, 1416 ** those are left as uint32_t. 1417 */ 1418 if (k.i32 >= 0) k.id = CTID_INT32; 1419 } else { 1420 /* OTOH it's common practice and even mandated by some ABIs 1421 ** that the enum type itself is unsigned, unless there are any 1422 ** negative constants. 1423 */ 1424 k.id = CTID_INT32; 1425 if (k.i32 < 0) einfo = CTINFO(CT_ENUM, CTALIGN(2) + CTID_INT32); 1426 } 1427 } 1428 /* Add named enum constant. */ 1429 { 1430 CType *ct; 1431 CTypeID constid = lj_ctype_new(cp->cts, &ct); 1432 ctype_get(cp->cts, lastid)->sib = constid; 1433 lastid = constid; 1434 ctype_setname(ct, name); 1435 ct->info = CTINFO(CT_CONSTVAL, CTF_CONST|k.id); 1436 ct->size = k.u32++; 1437 if (k.u32 == 0x80000000u) k.id = CTID_UINT32; 1438 lj_ctype_addname(cp->cts, ct, constid); 1439 } 1440 if (!cp_opt(cp, ',')) break; 1441 } while (cp->tok != '}'); /* Trailing ',' is ok. */ 1442 cp_check(cp, '}'); 1443 /* Complete enum. */ 1444 ctype_get(cp->cts, eid)->info = einfo; 1445 ctype_get(cp->cts, eid)->size = esize; 1446 } 1447 return eid; 1448 } 1449 1450 /* Parse declaration specifiers. */ 1451 static CPscl cp_decl_spec(CPState *cp, CPDecl *decl, CPscl scl) 1452 { 1453 uint32_t cds = 0, sz = 0; 1454 CTypeID tdef = 0; 1455 1456 decl->cp = cp; 1457 decl->mode = cp->mode; 1458 decl->name = NULL; 1459 decl->redir = NULL; 1460 decl->attr = 0; 1461 decl->fattr = 0; 1462 decl->pos = decl->top = 0; 1463 decl->stack[0].next = 0; 1464 1465 for (;;) { /* Parse basic types. */ 1466 cp_decl_attributes(cp, decl); 1467 if (cp->tok >= CTOK_FIRSTDECL && cp->tok <= CTOK_LASTDECLFLAG) { 1468 uint32_t cbit; 1469 if (cp->ct->size) { 1470 if (sz) goto end_decl; 1471 sz = cp->ct->size; 1472 } 1473 cbit = (1u << (cp->tok - CTOK_FIRSTDECL)); 1474 cds = cds | cbit | ((cbit & cds & CDF_LONG) << 1); 1475 if (cp->tok >= CTOK_FIRSTSCL) { 1476 if (!(scl & cbit)) cp_errmsg(cp, cp->tok, LJ_ERR_FFI_BADSCL); 1477 } else if (tdef) { 1478 goto end_decl; 1479 } 1480 cp_next(cp); 1481 continue; 1482 } 1483 if (sz || tdef || 1484 (cds & (CDF_SHORT|CDF_LONG|CDF_SIGNED|CDF_UNSIGNED|CDF_COMPLEX))) 1485 break; 1486 switch (cp->tok) { 1487 case CTOK_STRUCT: 1488 tdef = cp_decl_struct(cp, decl, CTINFO(CT_STRUCT, 0)); 1489 continue; 1490 case CTOK_UNION: 1491 tdef = cp_decl_struct(cp, decl, CTINFO(CT_STRUCT, CTF_UNION)); 1492 continue; 1493 case CTOK_ENUM: 1494 tdef = cp_decl_enum(cp, decl); 1495 continue; 1496 case CTOK_IDENT: 1497 if (ctype_istypedef(cp->ct->info)) { 1498 tdef = ctype_cid(cp->ct->info); /* Get typedef. */ 1499 cp_next(cp); 1500 continue; 1501 } 1502 break; 1503 case '$': 1504 tdef = cp->val.id; 1505 cp_next(cp); 1506 continue; 1507 default: 1508 break; 1509 } 1510 break; 1511 } 1512 end_decl: 1513 1514 if ((cds & CDF_COMPLEX)) /* Use predefined complex types. */ 1515 tdef = sz == 4 ? CTID_COMPLEX_FLOAT : CTID_COMPLEX_DOUBLE; 1516 1517 if (tdef) { 1518 cp_push_type(decl, tdef); 1519 } else if ((cds & CDF_VOID)) { 1520 cp_push(decl, CTINFO(CT_VOID, (decl->attr & CTF_QUAL)), CTSIZE_INVALID); 1521 decl->attr &= ~CTF_QUAL; 1522 } else { 1523 /* Determine type info and size. */ 1524 CTInfo info = CTINFO(CT_NUM, (cds & CDF_UNSIGNED) ? CTF_UNSIGNED : 0); 1525 if ((cds & CDF_BOOL)) { 1526 if ((cds & ~(CDF_SCL|CDF_BOOL|CDF_INT|CDF_SIGNED|CDF_UNSIGNED))) 1527 cp_errmsg(cp, 0, LJ_ERR_FFI_INVTYPE); 1528 info |= CTF_BOOL; 1529 if (!(cds & CDF_SIGNED)) info |= CTF_UNSIGNED; 1530 if (!sz) { 1531 sz = 1; 1532 } 1533 } else if ((cds & CDF_FP)) { 1534 info = CTINFO(CT_NUM, CTF_FP); 1535 if ((cds & CDF_LONG)) sz = sizeof(long double); 1536 } else if ((cds & CDF_CHAR)) { 1537 if ((cds & (CDF_CHAR|CDF_SIGNED|CDF_UNSIGNED)) == CDF_CHAR) 1538 info |= CTF_UCHAR; /* Handle platforms where char is unsigned. */ 1539 } else if ((cds & CDF_SHORT)) { 1540 sz = sizeof(short); 1541 } else if ((cds & CDF_LONGLONG)) { 1542 sz = 8; 1543 } else if ((cds & CDF_LONG)) { 1544 info |= CTF_LONG; 1545 sz = sizeof(long); 1546 } else if (!sz) { 1547 if (!(cds & (CDF_SIGNED|CDF_UNSIGNED))) 1548 cp_errmsg(cp, cp->tok, LJ_ERR_FFI_DECLSPEC); 1549 sz = sizeof(int); 1550 } 1551 lua_assert(sz != 0); 1552 info += CTALIGN(lj_fls(sz)); /* Use natural alignment. */ 1553 info += (decl->attr & CTF_QUAL); /* Merge qualifiers. */ 1554 cp_push(decl, info, sz); 1555 decl->attr &= ~CTF_QUAL; 1556 } 1557 decl->specpos = decl->pos; 1558 decl->specattr = decl->attr; 1559 decl->specfattr = decl->fattr; 1560 return (cds & CDF_SCL); /* Return storage class. */ 1561 } 1562 1563 /* Parse array declaration. */ 1564 static void cp_decl_array(CPState *cp, CPDecl *decl) 1565 { 1566 CTInfo info = CTINFO(CT_ARRAY, 0); 1567 CTSize nelem = CTSIZE_INVALID; /* Default size for a[] or a[?]. */ 1568 cp_decl_attributes(cp, decl); 1569 if (cp_opt(cp, '?')) 1570 info |= CTF_VLA; /* Create variable-length array a[?]. */ 1571 else if (cp->tok != ']') 1572 nelem = cp_expr_ksize(cp); 1573 cp_check(cp, ']'); 1574 cp_add(decl, info, nelem); 1575 } 1576 1577 /* Parse function declaration. */ 1578 static void cp_decl_func(CPState *cp, CPDecl *fdecl) 1579 { 1580 CTSize nargs = 0; 1581 CTInfo info = CTINFO(CT_FUNC, 0); 1582 CTypeID lastid = 0, anchor = 0; 1583 if (cp->tok != ')') { 1584 do { 1585 CPDecl decl; 1586 CTypeID ctypeid, fieldid; 1587 CType *ct; 1588 if (cp_opt(cp, '.')) { /* Vararg function. */ 1589 cp_check(cp, '.'); /* Workaround for the minimalistic lexer. */ 1590 cp_check(cp, '.'); 1591 info |= CTF_VARARG; 1592 break; 1593 } 1594 cp_decl_spec(cp, &decl, CDF_REGISTER); 1595 decl.mode = CPARSE_MODE_DIRECT|CPARSE_MODE_ABSTRACT; 1596 cp_declarator(cp, &decl); 1597 ctypeid = cp_decl_intern(cp, &decl); 1598 ct = ctype_raw(cp->cts, ctypeid); 1599 if (ctype_isvoid(ct->info)) 1600 break; 1601 else if (ctype_isrefarray(ct->info)) 1602 ctypeid = lj_ctype_intern(cp->cts, 1603 CTINFO(CT_PTR, CTALIGN_PTR|ctype_cid(ct->info)), CTSIZE_PTR); 1604 else if (ctype_isfunc(ct->info)) 1605 ctypeid = lj_ctype_intern(cp->cts, 1606 CTINFO(CT_PTR, CTALIGN_PTR|ctypeid), CTSIZE_PTR); 1607 /* Add new parameter. */ 1608 fieldid = lj_ctype_new(cp->cts, &ct); 1609 if (anchor) 1610 ctype_get(cp->cts, lastid)->sib = fieldid; 1611 else 1612 anchor = fieldid; 1613 lastid = fieldid; 1614 if (decl.name) ctype_setname(ct, decl.name); 1615 ct->info = CTINFO(CT_FIELD, ctypeid); 1616 ct->size = nargs++; 1617 } while (cp_opt(cp, ',')); 1618 } 1619 cp_check(cp, ')'); 1620 if (cp_opt(cp, '{')) { /* Skip function definition. */ 1621 int level = 1; 1622 cp->mode |= CPARSE_MODE_SKIP; 1623 for (;;) { 1624 if (cp->tok == '{') level++; 1625 else if (cp->tok == '}' && --level == 0) break; 1626 else if (cp->tok == CTOK_EOF) cp_err_token(cp, '}'); 1627 cp_next(cp); 1628 } 1629 cp->mode &= ~CPARSE_MODE_SKIP; 1630 cp->tok = ';'; /* Ok for cp_decl_multi(), error in cp_decl_single(). */ 1631 } 1632 info |= (fdecl->fattr & ~CTMASK_CID); 1633 fdecl->fattr = 0; 1634 fdecl->stack[cp_add(fdecl, info, nargs)].sib = anchor; 1635 } 1636 1637 /* Parse declarator. */ 1638 static void cp_declarator(CPState *cp, CPDecl *decl) 1639 { 1640 if (++cp->depth > CPARSE_MAX_DECLDEPTH) cp_err(cp, LJ_ERR_XLEVELS); 1641 1642 for (;;) { /* Head of declarator. */ 1643 if (cp_opt(cp, '*')) { /* Pointer. */ 1644 CTSize sz; 1645 CTInfo info; 1646 cp_decl_attributes(cp, decl); 1647 sz = CTSIZE_PTR; 1648 info = CTINFO(CT_PTR, CTALIGN_PTR); 1649 #if LJ_64 1650 if (ctype_msizeP(decl->attr) == 4) { 1651 sz = 4; 1652 info = CTINFO(CT_PTR, CTALIGN(2)); 1653 } 1654 #endif 1655 info += (decl->attr & (CTF_QUAL|CTF_REF)); 1656 decl->attr &= ~(CTF_QUAL|(CTMASK_MSIZEP<<CTSHIFT_MSIZEP)); 1657 cp_push(decl, info, sz); 1658 } else if (cp_opt(cp, '&') || cp_opt(cp, CTOK_ANDAND)) { /* Reference. */ 1659 decl->attr &= ~(CTF_QUAL|(CTMASK_MSIZEP<<CTSHIFT_MSIZEP)); 1660 cp_push(decl, CTINFO_REF(0), CTSIZE_PTR); 1661 } else { 1662 break; 1663 } 1664 } 1665 1666 if (cp_opt(cp, '(')) { /* Inner declarator. */ 1667 CPDeclIdx pos; 1668 cp_decl_attributes(cp, decl); 1669 /* Resolve ambiguity between inner declarator and 1st function parameter. */ 1670 if ((decl->mode & CPARSE_MODE_ABSTRACT) && 1671 (cp->tok == ')' || cp_istypedecl(cp))) goto func_decl; 1672 pos = decl->pos; 1673 cp_declarator(cp, decl); 1674 cp_check(cp, ')'); 1675 decl->pos = pos; 1676 } else if (cp->tok == CTOK_IDENT) { /* Direct declarator. */ 1677 if (!(decl->mode & CPARSE_MODE_DIRECT)) cp_err_token(cp, CTOK_EOF); 1678 decl->name = cp->str; 1679 decl->nameid = cp->val.id; 1680 cp_next(cp); 1681 } else { /* Abstract declarator. */ 1682 if (!(decl->mode & CPARSE_MODE_ABSTRACT)) cp_err_token(cp, CTOK_IDENT); 1683 } 1684 1685 for (;;) { /* Tail of declarator. */ 1686 if (cp_opt(cp, '[')) { /* Array. */ 1687 cp_decl_array(cp, decl); 1688 } else if (cp_opt(cp, '(')) { /* Function. */ 1689 func_decl: 1690 cp_decl_func(cp, decl); 1691 } else { 1692 break; 1693 } 1694 } 1695 1696 if ((decl->mode & CPARSE_MODE_FIELD) && cp_opt(cp, ':')) /* Field width. */ 1697 decl->bits = cp_expr_ksize(cp); 1698 1699 /* Process postfix attributes. */ 1700 cp_decl_attributes(cp, decl); 1701 cp_push_attributes(decl); 1702 1703 cp->depth--; 1704 } 1705 1706 /* Parse an abstract type declaration and return it's C type ID. */ 1707 static CTypeID cp_decl_abstract(CPState *cp) 1708 { 1709 CPDecl decl; 1710 cp_decl_spec(cp, &decl, 0); 1711 decl.mode = CPARSE_MODE_ABSTRACT; 1712 cp_declarator(cp, &decl); 1713 return cp_decl_intern(cp, &decl); 1714 } 1715 1716 /* Handle pragmas. */ 1717 static void cp_pragma(CPState *cp, BCLine pragmaline) 1718 { 1719 cp_next(cp); 1720 if (cp->tok == CTOK_IDENT && 1721 cp->str->hash == H_(e79b999f,42ca3e85)) { /* pack */ 1722 cp_next(cp); 1723 cp_check(cp, '('); 1724 if (cp->tok == CTOK_IDENT) { 1725 if (cp->str->hash == H_(738e923c,a1b65954)) { /* push */ 1726 if (cp->curpack < CPARSE_MAX_PACKSTACK) { 1727 cp->packstack[cp->curpack+1] = cp->packstack[cp->curpack]; 1728 cp->curpack++; 1729 } 1730 } else if (cp->str->hash == H_(6c71cf27,6c71cf27)) { /* pop */ 1731 if (cp->curpack > 0) cp->curpack--; 1732 } else { 1733 cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL); 1734 } 1735 cp_next(cp); 1736 if (!cp_opt(cp, ',')) goto end_pack; 1737 } 1738 if (cp->tok == CTOK_INTEGER) { 1739 cp->packstack[cp->curpack] = cp->val.u32 ? lj_fls(cp->val.u32) : 0; 1740 cp_next(cp); 1741 } else { 1742 cp->packstack[cp->curpack] = 255; 1743 } 1744 end_pack: 1745 cp_check(cp, ')'); 1746 } else { /* Ignore all other pragmas. */ 1747 while (cp->tok != CTOK_EOF && cp->linenumber == pragmaline) 1748 cp_next(cp); 1749 } 1750 } 1751 1752 /* Handle line number. */ 1753 static void cp_line(CPState *cp, BCLine hashline) 1754 { 1755 BCLine newline = cp->val.u32; 1756 /* TODO: Handle file name and include it in error messages. */ 1757 while (cp->tok != CTOK_EOF && cp->linenumber == hashline) 1758 cp_next(cp); 1759 cp->linenumber = newline; 1760 } 1761 1762 /* Parse multiple C declarations of types or extern identifiers. */ 1763 static void cp_decl_multi(CPState *cp) 1764 { 1765 int first = 1; 1766 while (cp->tok != CTOK_EOF) { 1767 CPDecl decl; 1768 CPscl scl; 1769 if (cp_opt(cp, ';')) { /* Skip empty statements. */ 1770 first = 0; 1771 continue; 1772 } 1773 if (cp->tok == '#') { /* Workaround, since we have no preprocessor, yet. */ 1774 BCLine hashline = cp->linenumber; 1775 CPToken tok = cp_next(cp); 1776 if (tok == CTOK_INTEGER) { 1777 cp_line(cp, hashline); 1778 continue; 1779 } else if (tok == CTOK_IDENT && 1780 cp->str->hash == H_(187aab88,fcb60b42)) { /* line */ 1781 if (cp_next(cp) != CTOK_INTEGER) cp_err_token(cp, tok); 1782 cp_line(cp, hashline); 1783 continue; 1784 } else if (tok == CTOK_IDENT && 1785 cp->str->hash == H_(f5e6b4f8,1d509107)) { /* pragma */ 1786 cp_pragma(cp, hashline); 1787 continue; 1788 } else { 1789 cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL); 1790 } 1791 } 1792 scl = cp_decl_spec(cp, &decl, CDF_TYPEDEF|CDF_EXTERN|CDF_STATIC); 1793 if ((cp->tok == ';' || cp->tok == CTOK_EOF) && 1794 ctype_istypedef(decl.stack[0].info)) { 1795 CTInfo info = ctype_rawchild(cp->cts, &decl.stack[0])->info; 1796 if (ctype_isstruct(info) || ctype_isenum(info)) 1797 goto decl_end; /* Accept empty declaration of struct/union/enum. */ 1798 } 1799 for (;;) { 1800 CTypeID ctypeid; 1801 cp_declarator(cp, &decl); 1802 ctypeid = cp_decl_intern(cp, &decl); 1803 if (decl.name && !decl.nameid) { /* NYI: redeclarations are ignored. */ 1804 CType *ct; 1805 CTypeID id; 1806 if ((scl & CDF_TYPEDEF)) { /* Create new typedef. */ 1807 id = lj_ctype_new(cp->cts, &ct); 1808 ct->info = CTINFO(CT_TYPEDEF, ctypeid); 1809 goto noredir; 1810 } else if (ctype_isfunc(ctype_get(cp->cts, ctypeid)->info)) { 1811 /* Treat both static and extern function declarations as extern. */ 1812 ct = ctype_get(cp->cts, ctypeid); 1813 /* We always get new anonymous functions (typedefs are copied). */ 1814 lua_assert(gcref(ct->name) == NULL); 1815 id = ctypeid; /* Just name it. */ 1816 } else if ((scl & CDF_STATIC)) { /* Accept static constants. */ 1817 id = cp_decl_constinit(cp, &ct, ctypeid); 1818 goto noredir; 1819 } else { /* External references have extern or no storage class. */ 1820 id = lj_ctype_new(cp->cts, &ct); 1821 ct->info = CTINFO(CT_EXTERN, ctypeid); 1822 } 1823 if (decl.redir) { /* Add attribute for redirected symbol name. */ 1824 CType *cta; 1825 CTypeID aid = lj_ctype_new(cp->cts, &cta); 1826 ct = ctype_get(cp->cts, id); /* Table may have been reallocated. */ 1827 cta->info = CTINFO(CT_ATTRIB, CTATTRIB(CTA_REDIR)); 1828 cta->sib = ct->sib; 1829 ct->sib = aid; 1830 ctype_setname(cta, decl.redir); 1831 } 1832 noredir: 1833 ctype_setname(ct, decl.name); 1834 lj_ctype_addname(cp->cts, ct, id); 1835 } 1836 if (!cp_opt(cp, ',')) break; 1837 cp_decl_reset(&decl); 1838 } 1839 decl_end: 1840 if (cp->tok == CTOK_EOF && first) break; /* May omit ';' for 1 decl. */ 1841 first = 0; 1842 cp_check(cp, ';'); 1843 } 1844 } 1845 1846 /* Parse a single C type declaration. */ 1847 static void cp_decl_single(CPState *cp) 1848 { 1849 CPDecl decl; 1850 cp_decl_spec(cp, &decl, 0); 1851 cp_declarator(cp, &decl); 1852 cp->val.id = cp_decl_intern(cp, &decl); 1853 if (cp->tok != CTOK_EOF) cp_err_token(cp, CTOK_EOF); 1854 } 1855 1856 #undef H_ 1857 1858 /* ------------------------------------------------------------------------ */ 1859 1860 /* Protected callback for C parser. */ 1861 static TValue *cpcparser(lua_State *L, lua_CFunction dummy, void *ud) 1862 { 1863 CPState *cp = (CPState *)ud; 1864 UNUSED(dummy); 1865 cframe_errfunc(L->cframe) = -1; /* Inherit error function. */ 1866 cp_init(cp); 1867 if ((cp->mode & CPARSE_MODE_MULTI)) 1868 cp_decl_multi(cp); 1869 else 1870 cp_decl_single(cp); 1871 if (cp->param && cp->param != cp->L->top) 1872 cp_err(cp, LJ_ERR_FFI_NUMPARAM); 1873 lua_assert(cp->depth == 0); 1874 return NULL; 1875 } 1876 1877 /* C parser. */ 1878 int lj_cparse(CPState *cp) 1879 { 1880 LJ_CTYPE_SAVE(cp->cts); 1881 int errcode = lj_vm_cpcall(cp->L, NULL, cp, cpcparser); 1882 if (errcode) 1883 LJ_CTYPE_RESTORE(cp->cts); 1884 cp_cleanup(cp); 1885 return errcode; 1886 } 1887 1888 #endif