2 ** C declaration parser.
3 ** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
14 #include "lj_cparse.h"
20 ** Important note: this is NOT a validating C parser! This is a minimal
21 ** C declaration parser, solely for use by the LuaJIT FFI.
23 ** It ought to return correct results for properly formed C declarations,
24 ** but it may accept some invalid declarations, too (and return nonsense).
25 ** Also, it shows rather generic error messages to avoid unnecessary bloat.
26 ** If in doubt, please check the input against your favorite C compiler.
29 /* -- C lexer ------------------------------------------------------------- */
31 /* C lexer token names. */
32 static const char *const ctoknames
[] = {
33 #define CTOKSTR(name, str) str,
39 /* Forward declaration. */
40 LJ_NORET
static void cp_err(CPState
*cp
, ErrMsg em
);
42 static const char *cp_tok2str(CPState
*cp
, CPToken tok
)
44 lua_assert(tok
< CTOK_FIRSTDECL
);
46 return ctoknames
[tok
-CTOK_OFS
-1];
47 else if (!lj_char_iscntrl(tok
))
48 return lj_str_pushf(cp
->L
, "%c", tok
);
50 return lj_str_pushf(cp
->L
, "char(%d)", tok
);
54 static LJ_AINLINE
int cp_iseol(CPChar c
)
56 return (c
== '\n' || c
== '\r');
59 static LJ_AINLINE CPChar
cp_get(CPState
*cp
);
61 /* Peek next raw character. */
62 static LJ_AINLINE CPChar
cp_rawpeek(CPState
*cp
)
64 return (CPChar
)(uint8_t)(*cp
->p
);
67 /* Transparently skip backslash-escaped line breaks. */
68 static LJ_NOINLINE CPChar
cp_get_bs(CPState
*cp
)
70 CPChar c2
, c
= cp_rawpeek(cp
);
71 if (!cp_iseol(c
)) return cp
->c
;
74 if (cp_iseol(c2
) && c2
!= c
) cp
->p
++;
79 /* Get next character. */
80 static LJ_AINLINE CPChar
cp_get(CPState
*cp
)
82 cp
->c
= (CPChar
)(uint8_t)(*cp
->p
++);
83 if (LJ_LIKELY(cp
->c
!= '\\')) return cp
->c
;
87 /* Grow save buffer. */
88 static LJ_NOINLINE
void cp_save_grow(CPState
*cp
, CPChar c
)
91 if (cp
->sb
.sz
>= CPARSE_MAX_BUF
/2)
92 cp_err(cp
, LJ_ERR_XELEM
);
93 newsize
= cp
->sb
.sz
* 2;
94 lj_str_resizebuf(cp
->L
, &cp
->sb
, newsize
);
95 cp
->sb
.buf
[cp
->sb
.n
++] = (char)c
;
98 /* Save character in buffer. */
99 static LJ_AINLINE
void cp_save(CPState
*cp
, CPChar c
)
101 if (LJ_UNLIKELY(cp
->sb
.n
+ 1 > cp
->sb
.sz
))
104 cp
->sb
.buf
[cp
->sb
.n
++] = (char)c
;
107 /* Skip line break. Handles "\n", "\r", "\r\n" or "\n\r". */
108 static void cp_newline(CPState
*cp
)
110 CPChar c
= cp_rawpeek(cp
);
111 if (cp_iseol(c
) && c
!= cp
->c
) cp
->p
++;
115 LJ_NORET
static void cp_errmsg(CPState
*cp
, CPToken tok
, ErrMsg em
, ...)
117 const char *msg
, *tokstr
;
122 } else if (tok
== CTOK_IDENT
|| tok
== CTOK_INTEGER
|| tok
== CTOK_STRING
||
123 tok
>= CTOK_FIRSTDECL
) {
127 tokstr
= cp_tok2str(cp
, tok
);
131 msg
= lj_str_pushvf(L
, err2msg(em
), argp
);
134 msg
= lj_str_pushf(L
, err2msg(LJ_ERR_XNEAR
), msg
, tokstr
);
135 if (cp
->linenumber
> 1)
136 msg
= lj_str_pushf(L
, "%s at line %d", msg
, cp
->linenumber
);
137 lj_err_callermsg(L
, msg
);
140 LJ_NORET LJ_NOINLINE
static void cp_err_token(CPState
*cp
, CPToken tok
)
142 cp_errmsg(cp
, cp
->tok
, LJ_ERR_XTOKEN
, cp_tok2str(cp
, tok
));
145 LJ_NORET LJ_NOINLINE
static void cp_err_badidx(CPState
*cp
, CType
*ct
)
147 GCstr
*s
= lj_ctype_repr(cp
->cts
->L
, ctype_typeid(cp
->cts
, ct
), NULL
);
148 cp_errmsg(cp
, 0, LJ_ERR_FFI_BADIDX
, strdata(s
));
151 LJ_NORET LJ_NOINLINE
static void cp_err(CPState
*cp
, ErrMsg em
)
153 cp_errmsg(cp
, 0, em
);
156 /* -- Main lexical scanner ------------------------------------------------ */
158 /* Parse integer literal. */
159 static CPToken
cp_integer(CPState
*cp
)
162 cp
->val
.id
= CTID_INT32
;
163 if (cp
->c
!= '0') { /* Decimal. */
165 n
= n
*10 + (cp
->c
- '0');
166 } while (lj_char_isdigit(cp_get(cp
)));
167 } else if ((cp_get(cp
)& ~0x20) == 'X') { /* Hexadecimal. */
168 if (!lj_char_isxdigit(cp_get(cp
)))
169 cp_err(cp
, LJ_ERR_XNUMBER
);
171 n
= n
*16 + (cp
->c
& 15);
172 if (!lj_char_isdigit(cp
->c
)) n
+= 9;
173 } while (lj_char_isxdigit(cp_get(cp
)));
174 if (n
>= 0x80000000u
) cp
->val
.id
= CTID_UINT32
;
175 } else { /* Octal. */
176 while (cp
->c
>= '0' && cp
->c
<= '7') {
177 n
= n
*8 + (cp
->c
- '0');
180 if (n
>= 0x80000000u
) cp
->val
.id
= CTID_UINT32
;
183 for (;;) { /* Parse suffixes. */
184 if ((cp
->c
& ~0x20) == 'U')
185 cp
->val
.id
= CTID_UINT32
;
186 else if ((cp
->c
& ~0x20) != 'L')
190 if (lj_char_isident(cp
->c
) && !(cp
->mode
& CPARSE_MODE_SKIP
))
191 cp_errmsg(cp
, cp
->c
, LJ_ERR_XNUMBER
);
195 /* Parse identifier or keyword. */
196 static CPToken
cp_ident(CPState
*cp
)
198 do { cp_save(cp
, cp
->c
); } while (lj_char_isident(cp_get(cp
)));
199 cp
->str
= lj_str_new(cp
->L
, cp
->sb
.buf
, cp
->sb
.n
);
200 cp
->val
.id
= lj_ctype_getname(cp
->cts
, &cp
->ct
, cp
->str
, cp
->tmask
);
201 if (ctype_type(cp
->ct
->info
) == CT_KW
)
202 return ctype_cid(cp
->ct
->info
);
206 /* Parse string or character constant. */
207 static CPToken
cp_string(CPState
*cp
)
209 CPChar delim
= cp
->c
;
211 while (cp
->c
!= delim
) {
213 if (c
== '\0') cp_errmsg(cp
, CTOK_EOF
, LJ_ERR_XSTR
);
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;
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));
233 if (lj_char_isdigit(c
)) {
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');
242 cp_save(cp
, (c
& 0xff));
253 cp
->str
= lj_str_new(cp
->L
, cp
->sb
.buf
, cp
->sb
.n
);
256 if (cp
->sb
.n
!= 1) cp_err_token(cp
, '\'');
257 cp
->val
.i32
= (int32_t)(char)cp
->sb
.buf
[0];
258 cp
->val
.id
= CTID_INT32
;
263 /* Skip C comment. */
264 static void cp_comment_c(CPState
*cp
)
267 if (cp_get(cp
) == '*') {
269 if (cp_get(cp
) == '/') { cp_get(cp
); return; }
270 } while (cp
->c
== '*');
272 if (cp_iseol(cp
->c
)) cp_newline(cp
);
273 } while (cp
->c
!= '\0');
276 /* Skip C++ comment. */
277 static void cp_comment_cpp(CPState
*cp
)
279 while (!cp_iseol(cp_get(cp
)) && cp
->c
!= '\0')
283 /* Lexical scanner for C. Only a minimal subset is implemented. */
284 static CPToken
cp_next_(CPState
*cp
)
286 lj_str_resetbuf(&cp
->sb
);
288 if (lj_char_isident(cp
->c
))
289 return lj_char_isdigit(cp
->c
) ? cp_integer(cp
) : cp_ident(cp
);
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
);
296 if (cp
->c
== '*') cp_comment_c(cp
);
297 else if (cp
->c
== '/') cp_comment_cpp(cp
);
301 cp_get(cp
); if (cp
->c
!= '|') return '|'; cp_get(cp
); return CTOK_OROR
;
303 cp_get(cp
); if (cp
->c
!= '&') return '&'; cp_get(cp
); return CTOK_ANDAND
;
305 cp_get(cp
); if (cp
->c
!= '=') return '='; cp_get(cp
); return CTOK_EQ
;
307 cp_get(cp
); if (cp
->c
!= '=') return '!'; cp_get(cp
); return CTOK_NE
;
310 if (cp
->c
== '=') { cp_get(cp
); return CTOK_LE
; }
311 else if (cp
->c
== '<') { cp_get(cp
); return CTOK_SHL
; }
315 if (cp
->c
== '=') { cp_get(cp
); return CTOK_GE
; }
316 else if (cp
->c
== '>') { cp_get(cp
); return CTOK_SHR
; }
319 cp_get(cp
); if (cp
->c
!= '>') return '-'; cp_get(cp
); return CTOK_DEREF
;
320 case '\0': return CTOK_EOF
;
321 default: { CPToken c
= cp
->c
; cp_get(cp
); return c
; }
326 static LJ_NOINLINE CPToken
cp_next(CPState
*cp
)
328 return (cp
->tok
= cp_next_(cp
));
331 /* -- C parser ------------------------------------------------------------ */
333 /* Namespaces for resolving identifiers. */
334 #define CPNS_DEFAULT \
335 ((1u<<CT_KW)|(1u<<CT_TYPEDEF)|(1u<<CT_FUNC)|(1u<<CT_EXTERN)|(1u<<CT_CONSTVAL))
336 #define CPNS_STRUCT ((1u<<CT_KW)|(1u<<CT_STRUCT)|(1u<<CT_ENUM))
338 typedef CTypeID CPDeclIdx
; /* Index into declaration stack. */
339 typedef uint32_t CPscl
; /* Storage class flags. */
341 /* Type declaration context. */
342 typedef struct CPDecl
{
343 CPDeclIdx top
; /* Top of declaration stack. */
344 CPDeclIdx pos
; /* Insertion position in declaration chain. */
345 CPDeclIdx specpos
; /* Saved position for declaration specifier. */
346 uint32_t mode
; /* Declarator mode. */
347 CPState
*cp
; /* C parser state. */
348 GCstr
*name
; /* Name of declared identifier (if direct). */
349 GCstr
*redir
; /* Redirected symbol name. */
350 CTypeID nameid
; /* Existing typedef for declared identifier. */
351 CTInfo attr
; /* Attributes. */
352 CTInfo fattr
; /* Function attributes. */
353 CTInfo specattr
; /* Saved attributes. */
354 CTInfo specfattr
; /* Saved function attributes. */
355 CTSize bits
; /* Field size in bits (if any). */
356 CType stack
[CPARSE_MAX_DECLSTACK
]; /* Type declaration stack. */
359 /* Forward declarations. */
360 static CPscl
cp_decl_spec(CPState
*cp
, CPDecl
*decl
, CPscl scl
);
361 static void cp_declarator(CPState
*cp
, CPDecl
*decl
);
362 static CTypeID
cp_decl_abstract(CPState
*cp
);
364 /* Initialize C parser state. Caller must set up: L, p, srcname, mode. */
365 static void cp_init(CPState
*cp
)
370 cp
->packstack
[0] = 255;
371 lj_str_initbuf(&cp
->sb
);
372 lj_str_resizebuf(cp
->L
, &cp
->sb
, LJ_MIN_SBUF
);
373 lua_assert(cp
->p
!= NULL
);
374 cp_get(cp
); /* Read-ahead first char. */
376 cp
->tmask
= CPNS_DEFAULT
;
377 cp_next(cp
); /* Read-ahead first token. */
380 /* Cleanup C parser state. */
381 static void cp_cleanup(CPState
*cp
)
383 global_State
*g
= G(cp
->L
);
384 lj_str_freebuf(g
, &cp
->sb
);
387 /* Check and consume optional token. */
388 static int cp_opt(CPState
*cp
, CPToken tok
)
390 if (cp
->tok
== tok
) { cp_next(cp
); return 1; }
394 /* Check and consume token. */
395 static void cp_check(CPState
*cp
, CPToken tok
)
397 if (cp
->tok
!= tok
) cp_err_token(cp
, tok
);
401 /* Check if the next token may start a type declaration. */
402 static int cp_istypedecl(CPState
*cp
)
404 if (cp
->tok
>= CTOK_FIRSTDECL
&& cp
->tok
<= CTOK_LASTDECL
) return 1;
405 if (cp
->tok
== CTOK_IDENT
&& ctype_istypedef(cp
->ct
->info
)) return 1;
409 /* -- Constant expression evaluator --------------------------------------- */
411 /* Forward declarations. */
412 static void cp_expr_unary(CPState
*cp
, CPValue
*k
);
413 static void cp_expr_sub(CPState
*cp
, CPValue
*k
, int pri
);
415 /* Please note that type handling is very weak here. Most ops simply
416 ** assume integer operands. Accessors are only needed to compute types and
417 ** return synthetic values. The only purpose of the expression evaluator
418 ** is to compute the values of constant expressions one would typically
419 ** find in C header files. And again: this is NOT a validating C parser!
422 /* Parse comma separated expression and return last result. */
423 static void cp_expr_comma(CPState
*cp
, CPValue
*k
)
425 do { cp_expr_sub(cp
, k
, 0); } while (cp_opt(cp
, ','));
428 /* Parse sizeof/alignof operator. */
429 static void cp_expr_sizeof(CPState
*cp
, CPValue
*k
, int wantsz
)
433 if (cp_opt(cp
, '(')) {
434 if (cp_istypedecl(cp
))
435 k
->id
= cp_decl_abstract(cp
);
437 cp_expr_comma(cp
, k
);
440 cp_expr_unary(cp
, k
);
442 info
= lj_ctype_info(cp
->cts
, k
->id
, &sz
);
444 if (sz
!= CTSIZE_INVALID
)
446 else if (k
->id
!= CTID_A_CCHAR
) /* Special case for sizeof("string"). */
447 cp_err(cp
, LJ_ERR_FFI_INVSIZE
);
449 k
->u32
= 1u << ctype_align(info
);
451 k
->id
= CTID_UINT32
; /* Really size_t. */
454 /* Parse prefix operators. */
455 static void cp_expr_prefix(CPState
*cp
, CPValue
*k
)
457 if (cp
->tok
== CTOK_INTEGER
) {
458 *k
= cp
->val
; cp_next(cp
);
459 } else if (cp_opt(cp
, '+')) {
460 cp_expr_unary(cp
, k
); /* Nothing to do (well, integer promotion). */
461 } else if (cp_opt(cp
, '-')) {
462 cp_expr_unary(cp
, k
); k
->i32
= -k
->i32
;
463 } else if (cp_opt(cp
, '~')) {
464 cp_expr_unary(cp
, k
); k
->i32
= ~k
->i32
;
465 } else if (cp_opt(cp
, '!')) {
466 cp_expr_unary(cp
, k
); k
->i32
= !k
->i32
; k
->id
= CTID_INT32
;
467 } else if (cp_opt(cp
, '(')) {
468 if (cp_istypedecl(cp
)) { /* Cast operator. */
469 CTypeID id
= cp_decl_abstract(cp
);
471 cp_expr_unary(cp
, k
);
472 k
->id
= id
; /* No conversion performed. */
473 } else { /* Sub-expression. */
474 cp_expr_comma(cp
, k
);
477 } else if (cp_opt(cp
, '*')) { /* Indirection. */
479 cp_expr_unary(cp
, k
);
480 ct
= lj_ctype_rawref(cp
->cts
, k
->id
);
481 if (!ctype_ispointer(ct
->info
))
482 cp_err_badidx(cp
, ct
);
483 k
->u32
= 0; k
->id
= ctype_cid(ct
->info
);
484 } else if (cp_opt(cp
, '&')) { /* Address operator. */
485 cp_expr_unary(cp
, k
);
486 k
->id
= lj_ctype_intern(cp
->cts
, CTINFO(CT_PTR
, CTALIGN_PTR
+k
->id
),
488 } else if (cp_opt(cp
, CTOK_SIZEOF
)) {
489 cp_expr_sizeof(cp
, k
, 1);
490 } else if (cp_opt(cp
, CTOK_ALIGNOF
)) {
491 cp_expr_sizeof(cp
, k
, 0);
492 } else if (cp
->tok
== CTOK_IDENT
) {
493 if (ctype_type(cp
->ct
->info
) == CT_CONSTVAL
) {
494 k
->u32
= cp
->ct
->size
; k
->id
= ctype_cid(cp
->ct
->info
);
495 } else if (ctype_type(cp
->ct
->info
) == CT_EXTERN
) {
496 k
->u32
= cp
->val
.id
; k
->id
= ctype_cid(cp
->ct
->info
);
497 } else if (ctype_type(cp
->ct
->info
) == CT_FUNC
) {
498 k
->u32
= cp
->val
.id
; k
->id
= cp
->val
.id
;
503 } else if (cp
->tok
== CTOK_STRING
) {
504 CTSize sz
= cp
->str
->len
;
505 while (cp_next(cp
) == CTOK_STRING
)
508 k
->id
= CTID_A_CCHAR
;
511 cp_errmsg(cp
, cp
->tok
, LJ_ERR_XSYMBOL
);
515 /* Parse postfix operators. */
516 static void cp_expr_postfix(CPState
*cp
, CPValue
*k
)
520 if (cp_opt(cp
, '[')) { /* Array/pointer index. */
522 cp_expr_comma(cp
, &k2
);
523 ct
= lj_ctype_rawref(cp
->cts
, k
->id
);
524 if (!ctype_ispointer(ct
->info
)) {
525 ct
= lj_ctype_rawref(cp
->cts
, k2
.id
);
526 if (!ctype_ispointer(ct
->info
))
527 cp_err_badidx(cp
, ct
);
531 } else if (cp
->tok
== '.' || cp
->tok
== CTOK_DEREF
) { /* Struct deref. */
534 ct
= lj_ctype_rawref(cp
->cts
, k
->id
);
535 if (cp
->tok
== CTOK_DEREF
) {
536 if (!ctype_ispointer(ct
->info
))
537 cp_err_badidx(cp
, ct
);
538 ct
= lj_ctype_rawref(cp
->cts
, ctype_cid(ct
->info
));
541 if (cp
->tok
!= CTOK_IDENT
) cp_err_token(cp
, CTOK_IDENT
);
542 if (!ctype_isstruct(ct
->info
) || ct
->size
== CTSIZE_INVALID
||
543 !(fct
= lj_ctype_getfield(cp
->cts
, ct
, cp
->str
, &ofs
)) ||
544 ctype_isbitfield(fct
->info
)) {
545 GCstr
*s
= lj_ctype_repr(cp
->cts
->L
, ctype_typeid(cp
->cts
, ct
), NULL
);
546 cp_errmsg(cp
, 0, LJ_ERR_FFI_BADMEMBER
, strdata(s
), strdata(cp
->str
));
549 k
->u32
= ctype_isconstval(ct
->info
) ? ct
->size
: 0;
554 k
->id
= ctype_cid(ct
->info
);
558 /* Parse infix operators. */
559 static void cp_expr_infix(CPState
*cp
, CPValue
*k
, int pri
)
562 k2
.u32
= 0; k2
.id
= 0; /* Silence the compiler. */
566 if (cp_opt(cp
, '?')) {
568 cp_expr_comma(cp
, &k2
); /* Right-associative. */
570 cp_expr_sub(cp
, &k3
, 0);
571 k
->u32
= k
->u32
? k2
.u32
: k3
.u32
;
572 k
->id
= k2
.id
> k3
.id
? k2
.id
: k3
.id
;
576 if (cp_opt(cp
, CTOK_OROR
)) {
577 cp_expr_sub(cp
, &k2
, 2); k
->i32
= k
->u32
|| k2
.u32
; k
->id
= CTID_INT32
;
581 if (cp_opt(cp
, CTOK_ANDAND
)) {
582 cp_expr_sub(cp
, &k2
, 3); k
->i32
= k
->u32
&& k2
.u32
; k
->id
= CTID_INT32
;
586 if (cp_opt(cp
, '|')) {
587 cp_expr_sub(cp
, &k2
, 4); k
->u32
= k
->u32
| k2
.u32
; goto arith_result
;
590 if (cp_opt(cp
, '^')) {
591 cp_expr_sub(cp
, &k2
, 5); k
->u32
= k
->u32
^ k2
.u32
; goto arith_result
;
594 if (cp_opt(cp
, '&')) {
595 cp_expr_sub(cp
, &k2
, 6); k
->u32
= k
->u32
& k2
.u32
; goto arith_result
;
598 if (cp_opt(cp
, CTOK_EQ
)) {
599 cp_expr_sub(cp
, &k2
, 7); k
->i32
= k
->u32
== k2
.u32
; k
->id
= CTID_INT32
;
601 } else if (cp_opt(cp
, CTOK_NE
)) {
602 cp_expr_sub(cp
, &k2
, 7); k
->i32
= k
->u32
!= k2
.u32
; k
->id
= CTID_INT32
;
606 if (cp_opt(cp
, '<')) {
607 cp_expr_sub(cp
, &k2
, 8);
608 if (k
->id
== CTID_INT32
&& k2
.id
== CTID_INT32
)
609 k
->i32
= k
->i32
< k2
.i32
;
611 k
->i32
= k
->u32
< k2
.u32
;
614 } else if (cp_opt(cp
, '>')) {
615 cp_expr_sub(cp
, &k2
, 8);
616 if (k
->id
== CTID_INT32
&& k2
.id
== CTID_INT32
)
617 k
->i32
= k
->i32
> k2
.i32
;
619 k
->i32
= k
->u32
> k2
.u32
;
622 } else if (cp_opt(cp
, CTOK_LE
)) {
623 cp_expr_sub(cp
, &k2
, 8);
624 if (k
->id
== CTID_INT32
&& k2
.id
== CTID_INT32
)
625 k
->i32
= k
->i32
<= k2
.i32
;
627 k
->i32
= k
->u32
<= k2
.u32
;
630 } else if (cp_opt(cp
, CTOK_GE
)) {
631 cp_expr_sub(cp
, &k2
, 8);
632 if (k
->id
== CTID_INT32
&& k2
.id
== CTID_INT32
)
633 k
->i32
= k
->i32
>= k2
.i32
;
635 k
->i32
= k
->u32
>= k2
.u32
;
640 if (cp_opt(cp
, CTOK_SHL
)) {
641 cp_expr_sub(cp
, &k2
, 9); k
->u32
= k
->u32
<< k2
.u32
;
643 } else if (cp_opt(cp
, CTOK_SHR
)) {
644 cp_expr_sub(cp
, &k2
, 9);
645 if (k
->id
== CTID_INT32
)
646 k
->i32
= k
->i32
>> k2
.i32
;
648 k
->u32
= k
->u32
>> k2
.u32
;
652 if (cp_opt(cp
, '+')) {
653 cp_expr_sub(cp
, &k2
, 10); k
->u32
= k
->u32
+ k2
.u32
;
655 if (k2
.id
> k
->id
) k
->id
= k2
.id
; /* Trivial promotion to unsigned. */
657 } else if (cp_opt(cp
, '-')) {
658 cp_expr_sub(cp
, &k2
, 10); k
->u32
= k
->u32
- k2
.u32
; goto arith_result
;
661 if (cp_opt(cp
, '*')) {
662 cp_expr_unary(cp
, &k2
); k
->u32
= k
->u32
* k2
.u32
; goto arith_result
;
663 } else if (cp_opt(cp
, '/')) {
664 cp_expr_unary(cp
, &k2
);
665 if (k2
.id
> k
->id
) k
->id
= k2
.id
; /* Trivial promotion to unsigned. */
667 (k
->id
== CTID_INT32
&& k
->u32
== 0x80000000u
&& k2
.i32
== -1))
668 cp_err(cp
, LJ_ERR_BADVAL
);
669 if (k
->id
== CTID_INT32
)
670 k
->i32
= k
->i32
/ k2
.i32
;
672 k
->u32
= k
->u32
/ k2
.u32
;
674 } else if (cp_opt(cp
, '%')) {
675 cp_expr_unary(cp
, &k2
);
676 if (k2
.id
> k
->id
) k
->id
= k2
.id
; /* Trivial promotion to unsigned. */
678 (k
->id
== CTID_INT32
&& k
->u32
== 0x80000000u
&& k2
.i32
== -1))
679 cp_err(cp
, LJ_ERR_BADVAL
);
680 if (k
->id
== CTID_INT32
)
681 k
->i32
= k
->i32
% k2
.i32
;
683 k
->u32
= k
->u32
% k2
.u32
;
692 /* Parse and evaluate unary expression. */
693 static void cp_expr_unary(CPState
*cp
, CPValue
*k
)
695 if (++cp
->depth
> CPARSE_MAX_DECLDEPTH
) cp_err(cp
, LJ_ERR_XLEVELS
);
696 cp_expr_prefix(cp
, k
);
697 cp_expr_postfix(cp
, k
);
701 /* Parse and evaluate sub-expression. */
702 static void cp_expr_sub(CPState
*cp
, CPValue
*k
, int pri
)
704 cp_expr_unary(cp
, k
);
705 cp_expr_infix(cp
, k
, pri
);
708 /* Parse constant integer expression. */
709 static void cp_expr_kint(CPState
*cp
, CPValue
*k
)
712 cp_expr_sub(cp
, k
, 0);
713 ct
= ctype_raw(cp
->cts
, k
->id
);
714 if (!ctype_isinteger(ct
->info
)) cp_err(cp
, LJ_ERR_BADVAL
);
717 /* Parse (non-negative) size expression. */
718 static CTSize
cp_expr_ksize(CPState
*cp
)
721 cp_expr_kint(cp
, &k
);
722 if (k
.u32
>= 0x80000000u
) cp_err(cp
, LJ_ERR_FFI_INVSIZE
);
726 /* -- Type declaration stack management ----------------------------------- */
728 /* Add declaration element behind the insertion position. */
729 static CPDeclIdx
cp_add(CPDecl
*decl
, CTInfo info
, CTSize size
)
731 CPDeclIdx top
= decl
->top
;
732 if (top
>= CPARSE_MAX_DECLSTACK
) cp_err(decl
->cp
, LJ_ERR_XLEVELS
);
733 decl
->stack
[top
].info
= info
;
734 decl
->stack
[top
].size
= size
;
735 decl
->stack
[top
].sib
= 0;
736 setgcrefnull(decl
->stack
[top
].name
);
737 decl
->stack
[top
].next
= decl
->stack
[decl
->pos
].next
;
738 decl
->stack
[decl
->pos
].next
= (CTypeID1
)top
;
743 /* Push declaration element before the insertion position. */
744 static CPDeclIdx
cp_push(CPDecl
*decl
, CTInfo info
, CTSize size
)
746 return (decl
->pos
= cp_add(decl
, info
, size
));
749 /* Push or merge attributes. */
750 static void cp_push_attributes(CPDecl
*decl
)
752 CType
*ct
= &decl
->stack
[decl
->pos
];
753 if (ctype_isfunc(ct
->info
)) { /* Ok to modify in-place. */
755 if ((decl
->fattr
& CTFP_CCONV
))
756 ct
->info
= (ct
->info
& (CTMASK_NUM
|CTF_VARARG
|CTMASK_CID
)) +
757 (decl
->fattr
& ~CTMASK_CID
);
760 if ((decl
->attr
& CTFP_ALIGNED
) && !(decl
->mode
& CPARSE_MODE_FIELD
))
761 cp_push(decl
, CTINFO(CT_ATTRIB
, CTATTRIB(CTA_ALIGN
)),
762 ctype_align(decl
->attr
));
766 /* Push unrolled type to declaration stack and merge qualifiers. */
767 static void cp_push_type(CPDecl
*decl
, CTypeID id
)
769 CType
*ct
= ctype_get(decl
->cp
->cts
, id
);
770 CTInfo info
= ct
->info
;
771 CTSize size
= ct
->size
;
772 switch (ctype_type(info
)) {
773 case CT_STRUCT
: case CT_ENUM
:
774 cp_push(decl
, CTINFO(CT_TYPEDEF
, id
), 0); /* Don't copy unique types. */
775 if ((decl
->attr
& CTF_QUAL
)) { /* Push unmerged qualifiers. */
776 cp_push(decl
, CTINFO(CT_ATTRIB
, CTATTRIB(CTA_QUAL
)),
777 (decl
->attr
& CTF_QUAL
));
778 decl
->attr
&= ~CTF_QUAL
;
782 if (ctype_isxattrib(info
, CTA_QUAL
))
783 decl
->attr
&= ~size
; /* Remove redundant qualifiers. */
784 cp_push_type(decl
, ctype_cid(info
)); /* Unroll. */
785 cp_push(decl
, info
& ~CTMASK_CID
, size
); /* Copy type. */
788 cp_push_type(decl
, ctype_cid(info
)); /* Unroll. */
789 cp_push(decl
, info
& ~CTMASK_CID
, size
); /* Copy type. */
790 decl
->stack
[decl
->pos
].sib
= 1; /* Mark as already checked and sized. */
791 /* Note: this is not copied to the ct->sib in the C type table. */
794 /* Copy type, link parameters (shared). */
795 decl
->stack
[cp_push(decl
, info
, size
)].sib
= ct
->sib
;
798 /* Copy type, merge common qualifiers. */
799 cp_push(decl
, info
|(decl
->attr
& CTF_QUAL
), size
);
800 decl
->attr
&= ~CTF_QUAL
;
805 /* Consume the declaration element chain and intern the C type. */
806 static CTypeID
cp_decl_intern(CPState
*cp
, CPDecl
*decl
)
810 CTSize csize
= CTSIZE_INVALID
;
813 CType
*ct
= &decl
->stack
[idx
];
814 CTInfo info
= ct
->info
;
815 CTInfo size
= ct
->size
;
816 /* The cid is already part of info for copies of pointers/functions. */
818 if (ctype_istypedef(info
)) {
820 id
= ctype_cid(info
);
821 /* Always refetch info/size, since struct/enum may have been completed. */
822 cinfo
= ctype_get(cp
->cts
, id
)->info
;
823 csize
= ctype_get(cp
->cts
, id
)->size
;
824 lua_assert(ctype_isstruct(cinfo
) || ctype_isenum(cinfo
));
825 } else if (ctype_isfunc(info
)) { /* Intern function. */
830 CType
*refct
= ctype_raw(cp
->cts
, id
);
831 /* Reject function or refarray return types. */
832 if (ctype_isfunc(refct
->info
) || ctype_isrefarray(refct
->info
))
833 cp_err(cp
, LJ_ERR_FFI_INVTYPE
);
835 /* No intervening attributes allowed, skip forward. */
837 CType
*ctn
= &decl
->stack
[idx
];
838 if (!ctype_isattrib(ctn
->info
)) break;
839 idx
= ctn
->next
; /* Skip attribute. */
841 sib
= ct
->sib
; /* Next line may reallocate the C type table. */
842 fid
= lj_ctype_new(cp
->cts
, &fct
);
843 csize
= CTSIZE_INVALID
;
844 fct
->info
= cinfo
= info
+ id
;
848 } else if (ctype_isattrib(info
)) {
849 if (ctype_isxattrib(info
, CTA_QUAL
))
851 else if (ctype_isxattrib(info
, CTA_ALIGN
))
852 CTF_INSERT(cinfo
, ALIGN
, size
);
853 id
= lj_ctype_intern(cp
->cts
, info
+id
, size
);
854 /* Inherit csize/cinfo from original type. */
856 if (ctype_isnum(info
)) { /* Handle mode/vector-size attributes. */
858 if (!(info
& CTF_BOOL
)) {
859 CTSize msize
= ctype_msizeP(decl
->attr
);
860 CTSize vsize
= ctype_vsizeP(decl
->attr
);
861 if (msize
&& (!(info
& CTF_FP
) || (msize
== 4 || msize
== 8))) {
862 CTSize malign
= lj_fls(msize
);
863 if (malign
> 4) malign
= 4; /* Limit alignment. */
864 CTF_INSERT(info
, ALIGN
, malign
);
865 size
= msize
; /* Override size via mode. */
867 if (vsize
) { /* Vector size set? */
868 CTSize esize
= lj_fls(size
);
869 if (vsize
>= esize
) {
870 /* Intern the element type first. */
871 id
= lj_ctype_intern(cp
->cts
, info
, size
);
872 /* Then create a vector (array) with vsize alignment. */
873 size
= (1u << vsize
);
874 if (vsize
> 4) vsize
= 4; /* Limit alignment. */
875 if (ctype_align(info
) > vsize
) vsize
= ctype_align(info
);
876 info
= CTINFO(CT_ARRAY
, (info
& CTF_QUAL
) + CTF_VECTOR
+
881 } else if (ctype_isptr(info
)) {
882 /* Reject pointer/ref to ref. */
883 if (id
&& ctype_isref(ctype_raw(cp
->cts
, id
)->info
))
884 cp_err(cp
, LJ_ERR_FFI_INVTYPE
);
885 if (ctype_isref(info
)) {
886 info
&= ~CTF_VOLATILE
; /* Refs are always const, never volatile. */
887 /* No intervening attributes allowed, skip forward. */
889 CType
*ctn
= &decl
->stack
[idx
];
890 if (!ctype_isattrib(ctn
->info
)) break;
891 idx
= ctn
->next
; /* Skip attribute. */
894 } else if (ctype_isarray(info
)) { /* Check for valid array size etc. */
895 if (ct
->sib
== 0) { /* Only check/size arrays not copied by unroll. */
896 if (ctype_isref(cinfo
)) /* Reject arrays of refs. */
897 cp_err(cp
, LJ_ERR_FFI_INVTYPE
);
898 /* Reject VLS or unknown-sized types. */
899 if (ctype_isvltype(cinfo
) || csize
== CTSIZE_INVALID
)
900 cp_err(cp
, LJ_ERR_FFI_INVSIZE
);
901 /* a[] and a[?] keep their invalid size. */
902 if (size
!= CTSIZE_INVALID
) {
903 uint64_t xsz
= (uint64_t)size
* csize
;
904 if (xsz
>= 0x80000000u
) cp_err(cp
, LJ_ERR_FFI_INVSIZE
);
908 info
|= (cinfo
& (CTF_QUAL
|CTF_ALIGN
)); /* Inherit qual and align. */
910 lua_assert(ctype_isvoid(info
));
914 id
= lj_ctype_intern(cp
->cts
, info
+id
, size
);
920 /* -- C declaration parser ------------------------------------------------ */
922 #define H_(le, be) LJ_ENDIAN_SELECT(0x##le, 0x##be)
924 /* Reset declaration state to declaration specifier. */
925 static void cp_decl_reset(CPDecl
*decl
)
927 decl
->pos
= decl
->specpos
;
928 decl
->top
= decl
->specpos
+1;
929 decl
->stack
[decl
->specpos
].next
= 0;
930 decl
->attr
= decl
->specattr
;
931 decl
->fattr
= decl
->specfattr
;
936 /* Parse constant initializer. */
937 /* NYI: FP constants and strings as initializers. */
938 static CTypeID
cp_decl_constinit(CPState
*cp
, CType
**ctp
, CTypeID
typeid)
940 CType
*ctt
= ctype_get(cp
->cts
, typeid);
945 while (ctype_isattrib(ctt
->info
)) { /* Skip attributes. */
946 typeid = ctype_cid(ctt
->info
); /* Update ID, too. */
947 ctt
= ctype_get(cp
->cts
, typeid);
951 if (!ctype_isinteger(info
) || !(info
& CTF_CONST
) || size
> 4)
952 cp_err(cp
, LJ_ERR_FFI_INVTYPE
);
954 cp_expr_sub(cp
, &k
, 0);
955 constid
= lj_ctype_new(cp
->cts
, ctp
);
956 (*ctp
)->info
= CTINFO(CT_CONSTVAL
, CTF_CONST
|typeid);
957 k
.u32
<<= 8*(4-size
);
958 if ((info
& CTF_UNSIGNED
))
959 k
.u32
>>= 8*(4-size
);
961 k
.u32
= (uint32_t)((int32_t)k
.u32
>> 8*(4-size
));
962 (*ctp
)->size
= k
.u32
;
966 /* Parse size in parentheses as part of attribute. */
967 static CTSize
cp_decl_sizeattr(CPState
*cp
)
970 uint32_t oldtmask
= cp
->tmask
;
971 cp
->tmask
= CPNS_DEFAULT
; /* Required for expression evaluator. */
973 sz
= cp_expr_ksize(cp
);
974 cp
->tmask
= oldtmask
;
979 /* Parse alignment attribute. */
980 static void cp_decl_align(CPState
*cp
, CPDecl
*decl
)
982 CTSize al
= 4; /* Unspecified alignment is 16 bytes. */
983 if (cp
->tok
== '(') {
984 al
= cp_decl_sizeattr(cp
);
985 al
= al
? lj_fls(al
) : 0;
987 CTF_INSERT(decl
->attr
, ALIGN
, al
);
988 decl
->attr
|= CTFP_ALIGNED
;
991 /* Parse GCC asm("name") redirect. */
992 static void cp_decl_asm(CPState
*cp
, CPDecl
*decl
)
997 if (cp
->tok
== CTOK_STRING
) {
998 GCstr
*str
= cp
->str
;
999 while (cp_next(cp
) == CTOK_STRING
) {
1000 lj_str_pushf(cp
->L
, "%s%s", strdata(str
), strdata(cp
->str
));
1002 str
= strV(cp
->L
->top
);
1009 /* Parse GCC __attribute__((mode(...))). */
1010 static void cp_decl_mode(CPState
*cp
, CPDecl
*decl
)
1013 if (cp
->tok
== CTOK_IDENT
) {
1014 const char *s
= strdata(cp
->str
);
1015 CTSize sz
= 0, vlen
= 0;
1016 if (s
[0] == '_' && s
[1] == '_') s
+= 2;
1020 if (*s
>= '0' && *s
<= '9')
1021 vlen
= vlen
*10 + (*s
++ - '0');
1024 case 'Q': sz
= 1; break;
1025 case 'H': sz
= 2; break;
1026 case 'S': sz
= 4; break;
1027 case 'D': sz
= 8; break;
1028 case 'T': sz
= 16; break;
1029 case 'O': sz
= 32; break;
1030 default: goto bad_size
;
1032 if (*s
== 'I' || *s
== 'F') {
1033 CTF_INSERT(decl
->attr
, MSIZEP
, sz
);
1034 if (vlen
) CTF_INSERT(decl
->attr
, VSIZEP
, lj_fls(vlen
*sz
));
1042 /* Parse GCC __attribute__((...)). */
1043 static void cp_decl_gccattribute(CPState
*cp
, CPDecl
*decl
)
1048 while (cp
->tok
!= ')') {
1049 if (cp
->tok
== CTOK_IDENT
) {
1050 GCstr
*attrstr
= cp
->str
;
1052 switch (attrstr
->hash
) {
1053 case H_(64a9208e
,8ce14319
): case H_(8e6331b2
,95a282af
): /* aligned */
1054 cp_decl_align(cp
, decl
);
1056 case H_(42eb47de
,f0ede26c
): case H_(29f48a09
,cf383e0c
): /* packed */
1057 decl
->attr
|= CTFP_PACKED
;
1059 case H_(0a84eef6
,8dfab04c
): case H_(995cf92c
,d5696591
): /* mode */
1060 cp_decl_mode(cp
, decl
);
1062 case H_(0ab31997
,2d5213fa
): case H_(bf875611
,200e9990
): /* vector_size */
1064 CTSize vsize
= cp_decl_sizeattr(cp
);
1065 if (vsize
) CTF_INSERT(decl
->attr
, VSIZEP
, lj_fls(vsize
));
1069 case H_(5ad22db8
,c689b848
): case H_(439150fa
,65ea78cb
): /* regparm */
1070 CTF_INSERT(decl
->fattr
, REGPARM
, cp_decl_sizeattr(cp
));
1071 decl
->fattr
|= CTFP_CCONV
;
1073 case H_(18fc0b98
,7ff4c074
): case H_(4e62abed
,0a747424
): /* cdecl */
1074 CTF_INSERT(decl
->fattr
, CCONV
, CTCC_CDECL
);
1075 decl
->fattr
|= CTFP_CCONV
;
1077 case H_(72b2e41b
,494c5a44
): case H_(f2356d59
,f25fc9bd
): /* thiscall */
1078 CTF_INSERT(decl
->fattr
, CCONV
, CTCC_THISCALL
);
1079 decl
->fattr
|= CTFP_CCONV
;
1081 case H_(0d0ffc42
,ab746f88
): case H_(21c54ba1
,7f0ca7e3
): /* fastcall */
1082 CTF_INSERT(decl
->fattr
, CCONV
, CTCC_FASTCALL
);
1083 decl
->fattr
|= CTFP_CCONV
;
1085 case H_(ef76b040
,9412e06a
): case H_(de56697b
,c750e6e1
): /* stdcall */
1086 CTF_INSERT(decl
->fattr
, CCONV
, CTCC_STDCALL
);
1087 decl
->fattr
|= CTFP_CCONV
;
1089 case H_(ea78b622
,f234bd8e
): case H_(252ffb06
,8d50f34b
): /* sseregparm */
1090 decl
->fattr
|= CTF_SSEREGPARM
;
1091 decl
->fattr
|= CTFP_CCONV
;
1094 default: /* Skip all other attributes. */
1097 } else if (cp
->tok
>= CTOK_FIRSTDECL
) { /* For __attribute((const)) etc. */
1100 if (cp_opt(cp
, '(')) {
1101 while (cp
->tok
!= ')' && cp
->tok
!= CTOK_EOF
) cp_next(cp
);
1107 if (!cp_opt(cp
, ',')) break;
1113 /* Parse MSVC __declspec(...). */
1114 static void cp_decl_msvcattribute(CPState
*cp
, CPDecl
*decl
)
1118 while (cp
->tok
== CTOK_IDENT
) {
1119 GCstr
*attrstr
= cp
->str
;
1121 switch (attrstr
->hash
) {
1122 case H_(bc2395fa
,98f267f8
): /* align */
1123 cp_decl_align(cp
, decl
);
1125 default: /* Ignore all other attributes. */
1126 if (cp_opt(cp
, '(')) {
1127 while (cp
->tok
!= ')' && cp
->tok
!= CTOK_EOF
) cp_next(cp
);
1136 /* Parse declaration attributes (and common qualifiers). */
1137 static void cp_decl_attributes(CPState
*cp
, CPDecl
*decl
)
1141 case CTOK_CONST
: decl
->attr
|= CTF_CONST
; break;
1142 case CTOK_VOLATILE
: decl
->attr
|= CTF_VOLATILE
; break;
1143 case CTOK_RESTRICT
: break; /* Ignore. */
1144 case CTOK_EXTENSION
: break; /* Ignore. */
1145 case CTOK_ATTRIBUTE
: cp_decl_gccattribute(cp
, decl
); continue;
1146 case CTOK_ASM
: cp_decl_asm(cp
, decl
); continue;
1147 case CTOK_DECLSPEC
: cp_decl_msvcattribute(cp
, decl
); continue;
1150 CTF_INSERT(decl
->fattr
, CCONV
, cp
->ct
->size
);
1151 decl
->fattr
|= CTFP_CCONV
;
1156 CTF_INSERT(decl
->attr
, MSIZEP
, cp
->ct
->size
);
1165 /* Parse struct/union/enum name. */
1166 static CTypeID
cp_struct_name(CPState
*cp
, CPDecl
*sdecl
, CTInfo info
)
1170 cp
->tmask
= CPNS_STRUCT
;
1172 cp_decl_attributes(cp
, sdecl
);
1173 cp
->tmask
= CPNS_DEFAULT
;
1174 if (cp
->tok
!= '{') {
1175 if (cp
->tok
!= CTOK_IDENT
) cp_err_token(cp
, CTOK_IDENT
);
1176 if (cp
->val
.id
) { /* Name of existing struct/union/enum. */
1179 if ((ct
->info
^ info
) & (CTMASK_NUM
|CTF_UNION
)) /* Wrong type. */
1180 cp_errmsg(cp
, 0, LJ_ERR_FFI_REDEF
, strdata(gco2str(gcref(ct
->name
))));
1181 } else { /* Create named, incomplete struct/union/enum. */
1182 if ((cp
->mode
& CPARSE_MODE_NOIMPLICIT
))
1183 cp_errmsg(cp
, 0, LJ_ERR_FFI_BADTAG
, strdata(cp
->str
));
1184 sid
= lj_ctype_new(cp
->cts
, &ct
);
1186 ct
->size
= CTSIZE_INVALID
;
1187 ctype_setname(ct
, cp
->str
);
1188 lj_ctype_addname(cp
->cts
, ct
, sid
);
1191 } else { /* Create anonymous, incomplete struct/union/enum. */
1192 sid
= lj_ctype_new(cp
->cts
, &ct
);
1194 ct
->size
= CTSIZE_INVALID
;
1196 if (cp
->tok
== '{') {
1197 if (ct
->size
!= CTSIZE_INVALID
|| ct
->sib
)
1198 cp_errmsg(cp
, 0, LJ_ERR_FFI_REDEF
, strdata(gco2str(gcref(ct
->name
))));
1199 ct
->sib
= 1; /* Indicate the type is currently being defined. */
1204 /* Determine field alignment. */
1205 static CTSize
cp_field_align(CPState
*cp
, CType
*ct
, CTInfo info
)
1207 CTSize align
= ctype_align(info
);
1208 UNUSED(cp
); UNUSED(ct
);
1209 #if (LJ_TARGET_X86 && !LJ_ABI_WIN) || (LJ_TARGET_ARM && __APPLE__)
1210 /* The SYSV i386 and iOS ABIs limit alignment of non-vector fields to 2^2. */
1211 if (align
> 2 && !(info
& CTFP_ALIGNED
)) {
1212 if (ctype_isarray(info
) && !(info
& CTF_VECTOR
)) {
1214 ct
= ctype_rawchild(cp
->cts
, ct
);
1216 } while (ctype_isarray(info
) && !(info
& CTF_VECTOR
));
1218 if (ctype_isnum(info
) || ctype_isenum(info
))
1225 /* Layout struct/union fields. */
1226 static void cp_struct_layout(CPState
*cp
, CTypeID sid
, CTInfo sattr
)
1228 CTSize bofs
= 0, bmaxofs
= 0; /* Bit offset and max. bit offset. */
1229 CTSize maxalign
= ctype_align(sattr
);
1230 CType
*sct
= ctype_get(cp
->cts
, sid
);
1231 CTInfo sinfo
= sct
->info
;
1232 CTypeID fieldid
= sct
->sib
;
1234 CType
*ct
= ctype_get(cp
->cts
, fieldid
);
1235 CTInfo attr
= ct
->size
; /* Field declaration attributes (temp.). */
1237 if (ctype_isfield(ct
->info
) ||
1238 (ctype_isxattrib(ct
->info
, CTA_SUBTYPE
) && attr
)) {
1239 CTSize align
, amask
; /* Alignment (pow2) and alignment mask (bits). */
1241 CTInfo info
= lj_ctype_info(cp
->cts
, ctype_cid(ct
->info
), &sz
);
1242 CTSize bsz
, csz
= 8*sz
; /* Field size and container size (in bits). */
1243 sinfo
|= (info
& (CTF_QUAL
|CTF_VLA
)); /* Merge pseudo-qualifiers. */
1245 /* Check for size overflow and determine alignment. */
1246 if (sz
>= 0x20000000u
|| bofs
+ csz
< bofs
) {
1247 if (!(sz
== CTSIZE_INVALID
&& ctype_isarray(info
) &&
1248 !(sinfo
& CTF_UNION
)))
1249 cp_err(cp
, LJ_ERR_FFI_INVSIZE
);
1250 csz
= sz
= 0; /* Treat a[] and a[?] as zero-sized. */
1252 align
= cp_field_align(cp
, ct
, info
);
1253 if (((attr
|sattr
) & CTFP_PACKED
) ||
1254 ((attr
& CTFP_ALIGNED
) && ctype_align(attr
) > align
))
1255 align
= ctype_align(attr
);
1256 if (cp
->packstack
[cp
->curpack
] < align
)
1257 align
= cp
->packstack
[cp
->curpack
];
1258 if (align
> maxalign
) maxalign
= align
;
1259 amask
= (8u << align
) - 1;
1261 bsz
= ctype_bitcsz(ct
->info
); /* Bitfield size (temp.). */
1262 if (bsz
== CTBSZ_FIELD
|| !ctype_isfield(ct
->info
)) {
1263 bsz
= csz
; /* Regular fields or subtypes always fill the container. */
1264 bofs
= (bofs
+ amask
) & ~amask
; /* Start new aligned field. */
1265 ct
->size
= (bofs
>> 3); /* Store field offset. */
1266 } else { /* Bitfield. */
1267 if (bsz
== 0 || (attr
& CTFP_ALIGNED
) ||
1268 (!((attr
|sattr
) & CTFP_PACKED
) && (bofs
& amask
) + bsz
> csz
))
1269 bofs
= (bofs
+ amask
) & ~amask
; /* Start new aligned field. */
1271 /* Prefer regular field over bitfield. */
1272 if (bsz
== csz
&& (bofs
& amask
) == 0) {
1273 ct
->info
= CTINFO(CT_FIELD
, ctype_cid(ct
->info
));
1274 ct
->size
= (bofs
>> 3); /* Store field offset. */
1276 ct
->info
= CTINFO(CT_BITFIELD
,
1277 (info
& (CTF_QUAL
|CTF_UNSIGNED
|CTF_BOOL
)) +
1278 (csz
<< (CTSHIFT_BITCSZ
-3)) + (bsz
<< CTSHIFT_BITBSZ
));
1280 ct
->info
+= ((csz
- (bofs
& (csz
-1)) - bsz
) << CTSHIFT_BITPOS
);
1282 ct
->info
+= ((bofs
& (csz
-1)) << CTSHIFT_BITPOS
);
1284 ct
->size
= ((bofs
& ~(csz
-1)) >> 3); /* Store container offset. */
1288 /* Determine next offset or max. offset. */
1289 if ((sinfo
& CTF_UNION
)) {
1290 if (bsz
> bmaxofs
) bmaxofs
= bsz
;
1294 } /* All other fields in the chain are already set up. */
1299 /* Complete struct/union. */
1300 sct
->info
= sinfo
+ CTALIGN(maxalign
);
1301 bofs
= (sinfo
& CTF_UNION
) ? bmaxofs
: bofs
;
1302 maxalign
= (8u << maxalign
) - 1;
1303 sct
->size
= (((bofs
+ maxalign
) & ~maxalign
) >> 3);
1306 /* Parse struct/union declaration. */
1307 static CTypeID
cp_decl_struct(CPState
*cp
, CPDecl
*sdecl
, CTInfo sinfo
)
1309 CTypeID sid
= cp_struct_name(cp
, sdecl
, sinfo
);
1310 if (cp_opt(cp
, '{')) { /* Struct/union definition. */
1311 CTypeID lastid
= sid
;
1313 while (cp
->tok
!= '}') {
1315 CPscl scl
= cp_decl_spec(cp
, &decl
, CDF_STATIC
);
1316 decl
.mode
= scl
? CPARSE_MODE_DIRECT
:
1317 CPARSE_MODE_DIRECT
|CPARSE_MODE_ABSTRACT
|CPARSE_MODE_FIELD
;
1322 if (lastdecl
) cp_err_token(cp
, '}');
1324 /* Parse field declarator. */
1325 decl
.bits
= CTSIZE_INVALID
;
1326 cp_declarator(cp
, &decl
);
1327 typeid = cp_decl_intern(cp
, &decl
);
1329 if ((scl
& CDF_STATIC
)) { /* Static constant in struct namespace. */
1331 CTypeID fieldid
= cp_decl_constinit(cp
, &ct
, typeid);
1332 ctype_get(cp
->cts
, lastid
)->sib
= fieldid
;
1334 ctype_setname(ct
, decl
.name
);
1336 CTSize bsz
= CTBSZ_FIELD
; /* Temp. for layout phase. */
1338 CTypeID fieldid
= lj_ctype_new(cp
->cts
, &ct
); /* Do this first. */
1339 CType
*tct
= ctype_raw(cp
->cts
, typeid);
1341 if (decl
.bits
== CTSIZE_INVALID
) { /* Regular field. */
1342 if (ctype_isarray(tct
->info
) && tct
->size
== CTSIZE_INVALID
)
1343 lastdecl
= 1; /* a[] or a[?] must be the last declared field. */
1345 /* Accept transparent struct/union/enum. */
1347 if (!((ctype_isstruct(tct
->info
) && !(tct
->info
& CTF_VLA
)) ||
1348 ctype_isenum(tct
->info
)))
1349 cp_err_token(cp
, CTOK_IDENT
);
1350 ct
->info
= CTINFO(CT_ATTRIB
, CTATTRIB(CTA_SUBTYPE
) + typeid);
1351 ct
->size
= ctype_isstruct(tct
->info
) ?
1352 (decl
.attr
|0x80000000u
) : 0; /* For layout phase. */
1355 } else { /* Bitfield. */
1357 if (!ctype_isinteger_or_bool(tct
->info
) ||
1358 (bsz
== 0 && decl
.name
) || 8*tct
->size
> CTBSZ_MAX
||
1359 bsz
> ((tct
->info
& CTF_BOOL
) ? 1 : 8*tct
->size
))
1360 cp_errmsg(cp
, ':', LJ_ERR_BADVAL
);
1363 /* Create temporary field for layout phase. */
1364 ct
->info
= CTINFO(CT_FIELD
, typeid + (bsz
<< CTSHIFT_BITCSZ
));
1365 ct
->size
= decl
.attr
;
1366 if (decl
.name
) ctype_setname(ct
, decl
.name
);
1369 ctype_get(cp
->cts
, lastid
)->sib
= fieldid
;
1372 if (!cp_opt(cp
, ',')) break;
1373 cp_decl_reset(&decl
);
1378 ctype_get(cp
->cts
, lastid
)->sib
= 0; /* Drop sib = 1 for empty structs. */
1379 cp_decl_attributes(cp
, sdecl
); /* Layout phase needs postfix attributes. */
1380 cp_struct_layout(cp
, sid
, sdecl
->attr
);
1385 /* Parse enum declaration. */
1386 static CTypeID
cp_decl_enum(CPState
*cp
, CPDecl
*sdecl
)
1388 CTypeID eid
= cp_struct_name(cp
, sdecl
, CTINFO(CT_ENUM
, CTID_VOID
));
1389 CTInfo einfo
= CTINFO(CT_ENUM
, CTALIGN(2) + CTID_UINT32
);
1390 CTSize esize
= 4; /* Only 32 bit enums are supported. */
1391 if (cp_opt(cp
, '{')) { /* Enum definition. */
1393 CTypeID lastid
= eid
;
1397 GCstr
*name
= cp
->str
;
1398 if (cp
->tok
!= CTOK_IDENT
) cp_err_token(cp
, CTOK_IDENT
);
1399 if (cp
->val
.id
) cp_errmsg(cp
, 0, LJ_ERR_FFI_REDEF
, strdata(name
));
1401 if (cp_opt(cp
, '=')) {
1402 cp_expr_kint(cp
, &k
);
1403 if (k
.id
== CTID_UINT32
) {
1404 /* C99 says that enum constants are always (signed) integers.
1405 ** But since unsigned constants like 0x80000000 are quite common,
1406 ** those are left as uint32_t.
1408 if (k
.i32
>= 0) k
.id
= CTID_INT32
;
1410 /* OTOH it's common practice and even mandated by some ABIs
1411 ** that the enum type itself is unsigned, unless there are any
1412 ** negative constants.
1415 if (k
.i32
< 0) einfo
= CTINFO(CT_ENUM
, CTALIGN(2) + CTID_INT32
);
1418 /* Add named enum constant. */
1421 CTypeID constid
= lj_ctype_new(cp
->cts
, &ct
);
1422 ctype_get(cp
->cts
, lastid
)->sib
= constid
;
1424 ctype_setname(ct
, name
);
1425 ct
->info
= CTINFO(CT_CONSTVAL
, CTF_CONST
|k
.id
);
1427 if (k
.u32
== 0x80000000u
) k
.id
= CTID_UINT32
;
1428 lj_ctype_addname(cp
->cts
, ct
, constid
);
1430 if (!cp_opt(cp
, ',')) break;
1431 } while (cp
->tok
!= '}'); /* Trailing ',' is ok. */
1433 /* Complete enum. */
1434 ctype_get(cp
->cts
, eid
)->info
= einfo
;
1435 ctype_get(cp
->cts
, eid
)->size
= esize
;
1440 /* Parse declaration specifiers. */
1441 static CPscl
cp_decl_spec(CPState
*cp
, CPDecl
*decl
, CPscl scl
)
1443 uint32_t cds
= 0, sz
= 0;
1447 decl
->mode
= cp
->mode
;
1452 decl
->pos
= decl
->top
= 0;
1453 decl
->stack
[0].next
= 0;
1455 for (;;) { /* Parse basic types. */
1456 cp_decl_attributes(cp
, decl
);
1459 tdef
= cp_decl_struct(cp
, decl
, CTINFO(CT_STRUCT
, 0));
1462 tdef
= cp_decl_struct(cp
, decl
, CTINFO(CT_STRUCT
, CTF_UNION
));
1465 tdef
= cp_decl_enum(cp
, decl
);
1468 if (!ctype_istypedef(cp
->ct
->info
) || sz
|| tdef
||
1469 (cds
& (CDF_SHORT
|CDF_LONG
|CDF_SIGNED
|CDF_UNSIGNED
|CDF_COMPLEX
)))
1471 tdef
= ctype_cid(cp
->ct
->info
); /* Get typedef. */
1475 if (cp
->tok
>= CTOK_FIRSTDECL
&& cp
->tok
<= CTOK_LASTDECLFLAG
) {
1478 if (sz
) goto end_decl
;
1481 cbit
= (1u << (cp
->tok
- CTOK_FIRSTDECL
));
1482 cds
= cds
| cbit
| ((cbit
& cds
& CDF_LONG
) << 1);
1483 if (cp
->tok
>= CTOK_FIRSTSCL
&& !(scl
& cbit
))
1484 cp_errmsg(cp
, cp
->tok
, LJ_ERR_FFI_BADSCL
);
1493 if ((cds
& CDF_COMPLEX
)) /* Use predefined complex types. */
1494 tdef
= sz
== 4 ? CTID_COMPLEX_FLOAT
: CTID_COMPLEX_DOUBLE
;
1497 cp_push_type(decl
, tdef
);
1498 } else if ((cds
& CDF_VOID
)) {
1499 cp_push(decl
, CTINFO(CT_VOID
, (decl
->attr
& CTF_QUAL
)), CTSIZE_INVALID
);
1500 decl
->attr
&= ~CTF_QUAL
;
1502 /* Determine type info and size. */
1503 CTInfo info
= CTINFO(CT_NUM
, (cds
& CDF_UNSIGNED
) ? CTF_UNSIGNED
: 0);
1504 if ((cds
& CDF_BOOL
)) {
1505 info
= CTINFO(CT_NUM
, CTF_UNSIGNED
|CTF_BOOL
);
1506 lua_assert(sz
== 1);
1507 } else if ((cds
& CDF_FP
)) {
1508 info
= CTINFO(CT_NUM
, CTF_FP
);
1509 if ((cds
& CDF_LONG
)) sz
= sizeof(long double);
1510 } else if ((cds
& CDF_CHAR
)) {
1511 if ((cds
& (CDF_CHAR
|CDF_SIGNED
|CDF_UNSIGNED
)) == CDF_CHAR
)
1512 info
|= CTF_UCHAR
; /* Handle platforms where char is unsigned. */
1513 } else if ((cds
& CDF_SHORT
)) {
1515 } else if ((cds
& CDF_LONGLONG
)) {
1517 } else if ((cds
& CDF_LONG
)) {
1521 if (!(cds
& (CDF_SIGNED
|CDF_UNSIGNED
)))
1522 cp_errmsg(cp
, cp
->tok
, LJ_ERR_FFI_DECLSPEC
);
1525 lua_assert(sz
!= 0);
1526 info
+= CTALIGN(lj_fls(sz
)); /* Use natural alignment. */
1527 info
+= (decl
->attr
& CTF_QUAL
); /* Merge qualifiers. */
1528 cp_push(decl
, info
, sz
);
1529 decl
->attr
&= ~CTF_QUAL
;
1531 decl
->specpos
= decl
->pos
;
1532 decl
->specattr
= decl
->attr
;
1533 decl
->specfattr
= decl
->fattr
;
1534 return (cds
& CDF_SCL
); /* Return storage class. */
1537 /* Parse array declaration. */
1538 static void cp_decl_array(CPState
*cp
, CPDecl
*decl
)
1540 CTInfo info
= CTINFO(CT_ARRAY
, 0);
1541 CTSize nelem
= CTSIZE_INVALID
; /* Default size for a[] or a[?]. */
1542 cp_decl_attributes(cp
, decl
);
1543 if (cp_opt(cp
, '?'))
1544 info
|= CTF_VLA
; /* Create variable-length array a[?]. */
1545 else if (cp
->tok
!= ']')
1546 nelem
= cp_expr_ksize(cp
);
1548 cp_add(decl
, info
, nelem
);
1551 /* Parse function declaration. */
1552 static void cp_decl_func(CPState
*cp
, CPDecl
*fdecl
)
1555 CTInfo info
= CTINFO(CT_FUNC
, 0);
1556 CTypeID lastid
= 0, anchor
= 0;
1557 if (cp
->tok
!= ')') {
1560 CTypeID
typeid, fieldid
;
1562 if (cp_opt(cp
, '.')) { /* Vararg function. */
1563 cp_check(cp
, '.'); /* Workaround for the minimalistic lexer. */
1568 cp_decl_spec(cp
, &decl
, CDF_REGISTER
);
1569 decl
.mode
= CPARSE_MODE_DIRECT
|CPARSE_MODE_ABSTRACT
;
1570 cp_declarator(cp
, &decl
);
1571 typeid = cp_decl_intern(cp
, &decl
);
1572 ct
= ctype_raw(cp
->cts
, typeid);
1573 if (ctype_isvoid(ct
->info
))
1575 else if (ctype_isrefarray(ct
->info
))
1576 typeid = lj_ctype_intern(cp
->cts
,
1577 CTINFO(CT_PTR
, CTALIGN_PTR
|ctype_cid(ct
->info
)), CTSIZE_PTR
);
1578 else if (ctype_isfunc(ct
->info
))
1579 typeid = lj_ctype_intern(cp
->cts
,
1580 CTINFO(CT_PTR
, CTALIGN_PTR
|typeid), CTSIZE_PTR
);
1581 /* Add new parameter. */
1582 fieldid
= lj_ctype_new(cp
->cts
, &ct
);
1584 ctype_get(cp
->cts
, lastid
)->sib
= fieldid
;
1588 if (decl
.name
) ctype_setname(ct
, decl
.name
);
1589 ct
->info
= CTINFO(CT_FIELD
, typeid);
1591 } while (cp_opt(cp
, ','));
1594 if (cp_opt(cp
, '{')) { /* Skip function definition. */
1596 cp
->mode
|= CPARSE_MODE_SKIP
;
1598 if (cp
->tok
== '{') level
++;
1599 else if (cp
->tok
== '}' && --level
== 0) break;
1600 else if (cp
->tok
== CTOK_EOF
) cp_err_token(cp
, '}');
1603 cp
->mode
&= ~CPARSE_MODE_SKIP
;
1604 cp
->tok
= ';'; /* Ok for cp_decl_multi(), error in cp_decl_single(). */
1606 info
|= (fdecl
->fattr
& ~CTMASK_CID
);
1608 fdecl
->stack
[cp_add(fdecl
, info
, nargs
)].sib
= anchor
;
1611 /* Parse declarator. */
1612 static void cp_declarator(CPState
*cp
, CPDecl
*decl
)
1614 if (++cp
->depth
> CPARSE_MAX_DECLDEPTH
) cp_err(cp
, LJ_ERR_XLEVELS
);
1616 for (;;) { /* Head of declarator. */
1617 if (cp_opt(cp
, '*')) { /* Pointer. */
1620 cp_decl_attributes(cp
, decl
);
1622 info
= CTINFO(CT_PTR
, CTALIGN_PTR
);
1624 if (ctype_msizeP(decl
->attr
) == 4) {
1626 info
= CTINFO(CT_PTR
, CTALIGN(2));
1629 info
+= (decl
->attr
& (CTF_QUAL
|CTF_REF
));
1630 decl
->attr
&= ~(CTF_QUAL
|(CTMASK_MSIZEP
<<CTSHIFT_MSIZEP
));
1631 cp_push(decl
, info
, sz
);
1632 } else if (cp_opt(cp
, '&') || cp_opt(cp
, CTOK_ANDAND
)) { /* Reference. */
1633 decl
->attr
&= ~(CTF_QUAL
|(CTMASK_MSIZEP
<<CTSHIFT_MSIZEP
));
1634 cp_push(decl
, CTINFO_REF(0), CTSIZE_PTR
);
1640 if (cp_opt(cp
, '(')) { /* Inner declarator. */
1642 cp_decl_attributes(cp
, decl
);
1643 /* Resolve ambiguity between inner declarator and 1st function parameter. */
1644 if ((decl
->mode
& CPARSE_MODE_ABSTRACT
) &&
1645 (cp
->tok
== ')' || cp_istypedecl(cp
))) goto func_decl
;
1647 cp_declarator(cp
, decl
);
1650 } else if (cp
->tok
== CTOK_IDENT
) { /* Direct declarator. */
1651 if (!(decl
->mode
& CPARSE_MODE_DIRECT
)) cp_err_token(cp
, CTOK_EOF
);
1652 decl
->name
= cp
->str
;
1653 decl
->nameid
= cp
->val
.id
;
1655 } else { /* Abstract declarator. */
1656 if (!(decl
->mode
& CPARSE_MODE_ABSTRACT
)) cp_err_token(cp
, CTOK_IDENT
);
1659 for (;;) { /* Tail of declarator. */
1660 if (cp_opt(cp
, '[')) { /* Array. */
1661 cp_decl_array(cp
, decl
);
1662 } else if (cp_opt(cp
, '(')) { /* Function. */
1664 cp_decl_func(cp
, decl
);
1670 if ((decl
->mode
& CPARSE_MODE_FIELD
) && cp_opt(cp
, ':')) /* Field width. */
1671 decl
->bits
= cp_expr_ksize(cp
);
1673 /* Process postfix attributes. */
1674 cp_decl_attributes(cp
, decl
);
1675 cp_push_attributes(decl
);
1680 /* Parse an abstract type declaration and return it's C type ID. */
1681 static CTypeID
cp_decl_abstract(CPState
*cp
)
1684 cp_decl_spec(cp
, &decl
, 0);
1685 decl
.mode
= CPARSE_MODE_ABSTRACT
;
1686 cp_declarator(cp
, &decl
);
1687 return cp_decl_intern(cp
, &decl
);
1690 /* Handle pragmas. */
1691 static void cp_pragma(CPState
*cp
, BCLine pragmaline
)
1694 if (cp
->tok
== CTOK_IDENT
&&
1695 cp
->str
->hash
== H_(e79b999f
,42ca3e85
)) { /* pack */
1698 if (cp
->tok
== CTOK_IDENT
) {
1699 if (cp
->str
->hash
== H_(738e923c
,a1b65954
)) { /* push */
1700 if (cp
->curpack
< CPARSE_MAX_PACKSTACK
) {
1701 cp
->packstack
[cp
->curpack
+1] = cp
->packstack
[cp
->curpack
];
1704 } else if (cp
->str
->hash
== H_(6c71cf27
,6c71cf27
)) { /* pop */
1705 if (cp
->curpack
> 0) cp
->curpack
--;
1707 cp_errmsg(cp
, cp
->tok
, LJ_ERR_XSYMBOL
);
1710 if (!cp_opt(cp
, ',')) goto end_pack
;
1712 if (cp
->tok
== CTOK_INTEGER
) {
1713 cp
->packstack
[cp
->curpack
] = cp
->val
.u32
? lj_fls(cp
->val
.u32
) : 0;
1716 cp
->packstack
[cp
->curpack
] = 255;
1720 } else { /* Ignore all other pragmas. */
1721 while (cp
->tok
!= CTOK_EOF
&& cp
->linenumber
== pragmaline
)
1726 /* Parse multiple C declarations of types or extern identifiers. */
1727 static void cp_decl_multi(CPState
*cp
)
1730 while (cp
->tok
!= CTOK_EOF
) {
1733 if (cp_opt(cp
, ';')) { /* Skip empty statements. */
1737 if (cp
->tok
== '#') { /* Workaround, since we have no preprocessor, yet. */
1738 BCLine pragmaline
= cp
->linenumber
;
1739 if (!(cp_next(cp
) == CTOK_IDENT
&&
1740 cp
->str
->hash
== H_(f5e6b4f8
,1d509107
))) /* pragma */
1741 cp_errmsg(cp
, cp
->tok
, LJ_ERR_XSYMBOL
);
1742 cp_pragma(cp
, pragmaline
);
1745 scl
= cp_decl_spec(cp
, &decl
, CDF_TYPEDEF
|CDF_EXTERN
|CDF_STATIC
);
1746 if ((cp
->tok
== ';' || cp
->tok
== CTOK_EOF
) &&
1747 ctype_istypedef(decl
.stack
[0].info
)) {
1748 CTInfo info
= ctype_rawchild(cp
->cts
, &decl
.stack
[0])->info
;
1749 if (ctype_isstruct(info
) || ctype_isenum(info
))
1750 goto decl_end
; /* Accept empty declaration of struct/union/enum. */
1754 cp_declarator(cp
, &decl
);
1755 typeid = cp_decl_intern(cp
, &decl
);
1756 if (decl
.name
&& !decl
.nameid
) { /* NYI: redeclarations are ignored. */
1759 if ((scl
& CDF_TYPEDEF
)) { /* Create new typedef. */
1760 id
= lj_ctype_new(cp
->cts
, &ct
);
1761 ct
->info
= CTINFO(CT_TYPEDEF
, typeid);
1763 } else if (ctype_isfunc(ctype_get(cp
->cts
, typeid)->info
)) {
1764 /* Treat both static and extern function declarations as extern. */
1765 ct
= ctype_get(cp
->cts
, typeid);
1766 /* We always get new anonymous functions (typedefs are copied). */
1767 lua_assert(gcref(ct
->name
) == NULL
);
1768 id
= typeid; /* Just name it. */
1769 } else if ((scl
& CDF_STATIC
)) { /* Accept static constants. */
1770 id
= cp_decl_constinit(cp
, &ct
, typeid);
1772 } else { /* External references have extern or no storage class. */
1773 id
= lj_ctype_new(cp
->cts
, &ct
);
1774 ct
->info
= CTINFO(CT_EXTERN
, typeid);
1776 if (decl
.redir
) { /* Add attribute for redirected symbol name. */
1778 CTypeID aid
= lj_ctype_new(cp
->cts
, &cta
);
1779 ct
= ctype_get(cp
->cts
, id
); /* Table may have been reallocated. */
1780 cta
->info
= CTINFO(CT_ATTRIB
, CTATTRIB(CTA_REDIR
));
1783 ctype_setname(cta
, decl
.redir
);
1786 ctype_setname(ct
, decl
.name
);
1787 lj_ctype_addname(cp
->cts
, ct
, id
);
1789 if (!cp_opt(cp
, ',')) break;
1790 cp_decl_reset(&decl
);
1793 if (cp
->tok
== CTOK_EOF
&& first
) break; /* May omit ';' for 1 decl. */
1799 /* Parse a single C type declaration. */
1800 static void cp_decl_single(CPState
*cp
)
1803 cp_decl_spec(cp
, &decl
, 0);
1804 cp_declarator(cp
, &decl
);
1805 cp
->val
.id
= cp_decl_intern(cp
, &decl
);
1806 if (cp
->tok
!= CTOK_EOF
) cp_err_token(cp
, CTOK_EOF
);
1811 /* ------------------------------------------------------------------------ */
1813 /* Protected callback for C parser. */
1814 static TValue
*cpcparser(lua_State
*L
, lua_CFunction dummy
, void *ud
)
1816 CPState
*cp
= (CPState
*)ud
;
1818 cframe_errfunc(L
->cframe
) = -1; /* Inherit error function. */
1820 if ((cp
->mode
& CPARSE_MODE_MULTI
))
1824 lua_assert(cp
->depth
== 0);
1829 int lj_cparse(CPState
*cp
)
1831 LJ_CTYPE_SAVE(cp
->cts
);
1832 int errcode
= lj_vm_cpcall(cp
->L
, NULL
, cp
, cpcparser
);
1834 LJ_CTYPE_RESTORE(cp
->cts
);