aboutsummaryrefslogtreecommitdiff
path: root/src/lj_cparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_cparse.c')
-rw-r--r--src/lj_cparse.c178
1 files changed, 107 insertions, 71 deletions
diff --git a/src/lj_cparse.c b/src/lj_cparse.c
index 9cd26d67..e364939d 100644
--- a/src/lj_cparse.c
+++ b/src/lj_cparse.c
@@ -9,13 +9,14 @@
9 9
10#include "lj_gc.h" 10#include "lj_gc.h"
11#include "lj_err.h" 11#include "lj_err.h"
12#include "lj_str.h" 12#include "lj_buf.h"
13#include "lj_ctype.h" 13#include "lj_ctype.h"
14#include "lj_cparse.h" 14#include "lj_cparse.h"
15#include "lj_frame.h" 15#include "lj_frame.h"
16#include "lj_vm.h" 16#include "lj_vm.h"
17#include "lj_char.h" 17#include "lj_char.h"
18#include "lj_strscan.h" 18#include "lj_strscan.h"
19#include "lj_strfmt.h"
19 20
20/* 21/*
21** Important note: this is NOT a validating C parser! This is a minimal 22** Important note: this is NOT a validating C parser! This is a minimal
@@ -27,6 +28,30 @@
27** If in doubt, please check the input against your favorite C compiler. 28** If in doubt, please check the input against your favorite C compiler.
28*/ 29*/
29 30
31#ifdef LUA_USE_ASSERT
32#define lj_assertCP(c, ...) (lj_assertG_(G(cp->L), (c), __VA_ARGS__))
33#else
34#define lj_assertCP(c, ...) ((void)cp)
35#endif
36
37/* -- Miscellaneous ------------------------------------------------------- */
38
39/* Match string against a C literal. */
40#define cp_str_is(str, k) \
41 ((str)->len == sizeof(k)-1 && !memcmp(strdata(str), k, sizeof(k)-1))
42
43/* Check string against a linear list of matches. */
44int lj_cparse_case(GCstr *str, const char *match)
45{
46 MSize len;
47 int n;
48 for (n = 0; (len = (MSize)*match++); n++, match += len) {
49 if (str->len == len && !memcmp(match, strdata(str), len))
50 return n;
51 }
52 return -1;
53}
54
30/* -- C lexer ------------------------------------------------------------- */ 55/* -- C lexer ------------------------------------------------------------- */
31 56
32/* C lexer token names. */ 57/* C lexer token names. */
@@ -42,13 +67,13 @@ LJ_NORET static void cp_err(CPState *cp, ErrMsg em);
42 67
43static const char *cp_tok2str(CPState *cp, CPToken tok) 68static const char *cp_tok2str(CPState *cp, CPToken tok)
44{ 69{
45 lua_assert(tok < CTOK_FIRSTDECL); 70 lj_assertCP(tok < CTOK_FIRSTDECL, "bad CPToken %d", tok);
46 if (tok > CTOK_OFS) 71 if (tok > CTOK_OFS)
47 return ctoknames[tok-CTOK_OFS-1]; 72 return ctoknames[tok-CTOK_OFS-1];
48 else if (!lj_char_iscntrl(tok)) 73 else if (!lj_char_iscntrl(tok))
49 return lj_str_pushf(cp->L, "%c", tok); 74 return lj_strfmt_pushf(cp->L, "%c", tok);
50 else 75 else
51 return lj_str_pushf(cp->L, "char(%d)", tok); 76 return lj_strfmt_pushf(cp->L, "char(%d)", tok);
52} 77}
53 78
54/* End-of-line? */ 79/* End-of-line? */
@@ -85,24 +110,10 @@ static LJ_NOINLINE CPChar cp_get_bs(CPState *cp)
85 return cp_get(cp); 110 return cp_get(cp);
86} 111}
87 112
88/* Grow save buffer. */
89static LJ_NOINLINE void cp_save_grow(CPState *cp, CPChar c)
90{
91 MSize newsize;
92 if (cp->sb.sz >= CPARSE_MAX_BUF/2)
93 cp_err(cp, LJ_ERR_XELEM);
94 newsize = cp->sb.sz * 2;
95 lj_str_resizebuf(cp->L, &cp->sb, newsize);
96 cp->sb.buf[cp->sb.n++] = (char)c;
97}
98
99/* Save character in buffer. */ 113/* Save character in buffer. */
100static LJ_AINLINE void cp_save(CPState *cp, CPChar c) 114static LJ_AINLINE void cp_save(CPState *cp, CPChar c)
101{ 115{
102 if (LJ_UNLIKELY(cp->sb.n + 1 > cp->sb.sz)) 116 lj_buf_putb(&cp->sb, c);
103 cp_save_grow(cp, c);
104 else
105 cp->sb.buf[cp->sb.n++] = (char)c;
106} 117}
107 118
108/* Skip line break. Handles "\n", "\r", "\r\n" or "\n\r". */ 119/* Skip line break. Handles "\n", "\r", "\r\n" or "\n\r". */
@@ -122,20 +133,20 @@ LJ_NORET static void cp_errmsg(CPState *cp, CPToken tok, ErrMsg em, ...)
122 tokstr = NULL; 133 tokstr = NULL;
123 } else if (tok == CTOK_IDENT || tok == CTOK_INTEGER || tok == CTOK_STRING || 134 } else if (tok == CTOK_IDENT || tok == CTOK_INTEGER || tok == CTOK_STRING ||
124 tok >= CTOK_FIRSTDECL) { 135 tok >= CTOK_FIRSTDECL) {
125 if (cp->sb.n == 0) cp_save(cp, '$'); 136 if (cp->sb.w == cp->sb.b) cp_save(cp, '$');
126 cp_save(cp, '\0'); 137 cp_save(cp, '\0');
127 tokstr = cp->sb.buf; 138 tokstr = cp->sb.b;
128 } else { 139 } else {
129 tokstr = cp_tok2str(cp, tok); 140 tokstr = cp_tok2str(cp, tok);
130 } 141 }
131 L = cp->L; 142 L = cp->L;
132 va_start(argp, em); 143 va_start(argp, em);
133 msg = lj_str_pushvf(L, err2msg(em), argp); 144 msg = lj_strfmt_pushvf(L, err2msg(em), argp);
134 va_end(argp); 145 va_end(argp);
135 if (tokstr) 146 if (tokstr)
136 msg = lj_str_pushf(L, err2msg(LJ_ERR_XNEAR), msg, tokstr); 147 msg = lj_strfmt_pushf(L, err2msg(LJ_ERR_XNEAR), msg, tokstr);
137 if (cp->linenumber > 1) 148 if (cp->linenumber > 1)
138 msg = lj_str_pushf(L, "%s at line %d", msg, cp->linenumber); 149 msg = lj_strfmt_pushf(L, "%s at line %d", msg, cp->linenumber);
139 lj_err_callermsg(L, msg); 150 lj_err_callermsg(L, msg);
140} 151}
141 152
@@ -164,7 +175,8 @@ static CPToken cp_number(CPState *cp)
164 TValue o; 175 TValue o;
165 do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp))); 176 do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp)));
166 cp_save(cp, '\0'); 177 cp_save(cp, '\0');
167 fmt = lj_strscan_scan((const uint8_t *)cp->sb.buf, &o, STRSCAN_OPT_C); 178 fmt = lj_strscan_scan((const uint8_t *)(cp->sb.b), sbuflen(&cp->sb)-1,
179 &o, STRSCAN_OPT_C);
168 if (fmt == STRSCAN_INT) cp->val.id = CTID_INT32; 180 if (fmt == STRSCAN_INT) cp->val.id = CTID_INT32;
169 else if (fmt == STRSCAN_U32) cp->val.id = CTID_UINT32; 181 else if (fmt == STRSCAN_U32) cp->val.id = CTID_UINT32;
170 else if (!(cp->mode & CPARSE_MODE_SKIP)) 182 else if (!(cp->mode & CPARSE_MODE_SKIP))
@@ -177,7 +189,7 @@ static CPToken cp_number(CPState *cp)
177static CPToken cp_ident(CPState *cp) 189static CPToken cp_ident(CPState *cp)
178{ 190{
179 do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp))); 191 do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp)));
180 cp->str = lj_str_new(cp->L, cp->sb.buf, cp->sb.n); 192 cp->str = lj_buf_str(cp->L, &cp->sb);
181 cp->val.id = lj_ctype_getname(cp->cts, &cp->ct, cp->str, cp->tmask); 193 cp->val.id = lj_ctype_getname(cp->cts, &cp->ct, cp->str, cp->tmask);
182 if (ctype_type(cp->ct->info) == CT_KW) 194 if (ctype_type(cp->ct->info) == CT_KW)
183 return ctype_cid(cp->ct->info); 195 return ctype_cid(cp->ct->info);
@@ -263,11 +275,11 @@ static CPToken cp_string(CPState *cp)
263 } 275 }
264 cp_get(cp); 276 cp_get(cp);
265 if (delim == '"') { 277 if (delim == '"') {
266 cp->str = lj_str_new(cp->L, cp->sb.buf, cp->sb.n); 278 cp->str = lj_buf_str(cp->L, &cp->sb);
267 return CTOK_STRING; 279 return CTOK_STRING;
268 } else { 280 } else {
269 if (cp->sb.n != 1) cp_err_token(cp, '\''); 281 if (sbuflen(&cp->sb) != 1) cp_err_token(cp, '\'');
270 cp->val.i32 = (int32_t)(char)cp->sb.buf[0]; 282 cp->val.i32 = (int32_t)(char)*cp->sb.b;
271 cp->val.id = CTID_INT32; 283 cp->val.id = CTID_INT32;
272 return CTOK_INTEGER; 284 return CTOK_INTEGER;
273 } 285 }
@@ -296,7 +308,7 @@ static void cp_comment_cpp(CPState *cp)
296/* Lexical scanner for C. Only a minimal subset is implemented. */ 308/* Lexical scanner for C. Only a minimal subset is implemented. */
297static CPToken cp_next_(CPState *cp) 309static CPToken cp_next_(CPState *cp)
298{ 310{
299 lj_str_resetbuf(&cp->sb); 311 lj_buf_reset(&cp->sb);
300 for (;;) { 312 for (;;) {
301 if (lj_char_isident(cp->c)) 313 if (lj_char_isident(cp->c))
302 return lj_char_isdigit(cp->c) ? cp_number(cp) : cp_ident(cp); 314 return lj_char_isdigit(cp->c) ? cp_number(cp) : cp_ident(cp);
@@ -385,9 +397,8 @@ static void cp_init(CPState *cp)
385 cp->depth = 0; 397 cp->depth = 0;
386 cp->curpack = 0; 398 cp->curpack = 0;
387 cp->packstack[0] = 255; 399 cp->packstack[0] = 255;
388 lj_str_initbuf(&cp->sb); 400 lj_buf_init(cp->L, &cp->sb);
389 lj_str_resizebuf(cp->L, &cp->sb, LJ_MIN_SBUF); 401 lj_assertCP(cp->p != NULL, "uninitialized cp->p");
390 lua_assert(cp->p != NULL);
391 cp_get(cp); /* Read-ahead first char. */ 402 cp_get(cp); /* Read-ahead first char. */
392 cp->tok = 0; 403 cp->tok = 0;
393 cp->tmask = CPNS_DEFAULT; 404 cp->tmask = CPNS_DEFAULT;
@@ -398,7 +409,7 @@ static void cp_init(CPState *cp)
398static void cp_cleanup(CPState *cp) 409static void cp_cleanup(CPState *cp)
399{ 410{
400 global_State *g = G(cp->L); 411 global_State *g = G(cp->L);
401 lj_str_freebuf(g, &cp->sb); 412 lj_buf_free(g, &cp->sb);
402} 413}
403 414
404/* Check and consume optional token. */ 415/* Check and consume optional token. */
@@ -848,12 +859,13 @@ static CTypeID cp_decl_intern(CPState *cp, CPDecl *decl)
848 /* The cid is already part of info for copies of pointers/functions. */ 859 /* The cid is already part of info for copies of pointers/functions. */
849 idx = ct->next; 860 idx = ct->next;
850 if (ctype_istypedef(info)) { 861 if (ctype_istypedef(info)) {
851 lua_assert(id == 0); 862 lj_assertCP(id == 0, "typedef not at toplevel");
852 id = ctype_cid(info); 863 id = ctype_cid(info);
853 /* Always refetch info/size, since struct/enum may have been completed. */ 864 /* Always refetch info/size, since struct/enum may have been completed. */
854 cinfo = ctype_get(cp->cts, id)->info; 865 cinfo = ctype_get(cp->cts, id)->info;
855 csize = ctype_get(cp->cts, id)->size; 866 csize = ctype_get(cp->cts, id)->size;
856 lua_assert(ctype_isstruct(cinfo) || ctype_isenum(cinfo)); 867 lj_assertCP(ctype_isstruct(cinfo) || ctype_isenum(cinfo),
868 "typedef of bad type");
857 } else if (ctype_isfunc(info)) { /* Intern function. */ 869 } else if (ctype_isfunc(info)) { /* Intern function. */
858 CType *fct; 870 CType *fct;
859 CTypeID fid; 871 CTypeID fid;
@@ -886,7 +898,7 @@ static CTypeID cp_decl_intern(CPState *cp, CPDecl *decl)
886 /* Inherit csize/cinfo from original type. */ 898 /* Inherit csize/cinfo from original type. */
887 } else { 899 } else {
888 if (ctype_isnum(info)) { /* Handle mode/vector-size attributes. */ 900 if (ctype_isnum(info)) { /* Handle mode/vector-size attributes. */
889 lua_assert(id == 0); 901 lj_assertCP(id == 0, "number not at toplevel");
890 if (!(info & CTF_BOOL)) { 902 if (!(info & CTF_BOOL)) {
891 CTSize msize = ctype_msizeP(decl->attr); 903 CTSize msize = ctype_msizeP(decl->attr);
892 CTSize vsize = ctype_vsizeP(decl->attr); 904 CTSize vsize = ctype_vsizeP(decl->attr);
@@ -941,7 +953,7 @@ static CTypeID cp_decl_intern(CPState *cp, CPDecl *decl)
941 info = (info & ~CTF_ALIGN) | (cinfo & CTF_ALIGN); 953 info = (info & ~CTF_ALIGN) | (cinfo & CTF_ALIGN);
942 info |= (cinfo & CTF_QUAL); /* Inherit qual. */ 954 info |= (cinfo & CTF_QUAL); /* Inherit qual. */
943 } else { 955 } else {
944 lua_assert(ctype_isvoid(info)); 956 lj_assertCP(ctype_isvoid(info), "bad ctype %08x", info);
945 } 957 }
946 csize = size; 958 csize = size;
947 cinfo = info+id; 959 cinfo = info+id;
@@ -953,8 +965,6 @@ static CTypeID cp_decl_intern(CPState *cp, CPDecl *decl)
953 965
954/* -- C declaration parser ------------------------------------------------ */ 966/* -- C declaration parser ------------------------------------------------ */
955 967
956#define H_(le, be) LJ_ENDIAN_SELECT(0x##le, 0x##be)
957
958/* Reset declaration state to declaration specifier. */ 968/* Reset declaration state to declaration specifier. */
959static void cp_decl_reset(CPDecl *decl) 969static void cp_decl_reset(CPDecl *decl)
960{ 970{
@@ -1031,7 +1041,7 @@ static void cp_decl_asm(CPState *cp, CPDecl *decl)
1031 if (cp->tok == CTOK_STRING) { 1041 if (cp->tok == CTOK_STRING) {
1032 GCstr *str = cp->str; 1042 GCstr *str = cp->str;
1033 while (cp_next(cp) == CTOK_STRING) { 1043 while (cp_next(cp) == CTOK_STRING) {
1034 lj_str_pushf(cp->L, "%s%s", strdata(str), strdata(cp->str)); 1044 lj_strfmt_pushf(cp->L, "%s%s", strdata(str), strdata(cp->str));
1035 cp->L->top--; 1045 cp->L->top--;
1036 str = strV(cp->L->top); 1046 str = strV(cp->L->top);
1037 } 1047 }
@@ -1083,44 +1093,57 @@ static void cp_decl_gccattribute(CPState *cp, CPDecl *decl)
1083 if (cp->tok == CTOK_IDENT) { 1093 if (cp->tok == CTOK_IDENT) {
1084 GCstr *attrstr = cp->str; 1094 GCstr *attrstr = cp->str;
1085 cp_next(cp); 1095 cp_next(cp);
1086 switch (attrstr->hash) { 1096 switch (lj_cparse_case(attrstr,
1087 case H_(64a9208e,8ce14319): case H_(8e6331b2,95a282af): /* aligned */ 1097 "\007aligned" "\013__aligned__"
1098 "\006packed" "\012__packed__"
1099 "\004mode" "\010__mode__"
1100 "\013vector_size" "\017__vector_size__"
1101#if LJ_TARGET_X86
1102 "\007regparm" "\013__regparm__"
1103 "\005cdecl" "\011__cdecl__"
1104 "\010thiscall" "\014__thiscall__"
1105 "\010fastcall" "\014__fastcall__"
1106 "\007stdcall" "\013__stdcall__"
1107 "\012sseregparm" "\016__sseregparm__"
1108#endif
1109 )) {
1110 case 0: case 1: /* aligned */
1088 cp_decl_align(cp, decl); 1111 cp_decl_align(cp, decl);
1089 break; 1112 break;
1090 case H_(42eb47de,f0ede26c): case H_(29f48a09,cf383e0c): /* packed */ 1113 case 2: case 3: /* packed */
1091 decl->attr |= CTFP_PACKED; 1114 decl->attr |= CTFP_PACKED;
1092 break; 1115 break;
1093 case H_(0a84eef6,8dfab04c): case H_(995cf92c,d5696591): /* mode */ 1116 case 4: case 5: /* mode */
1094 cp_decl_mode(cp, decl); 1117 cp_decl_mode(cp, decl);
1095 break; 1118 break;
1096 case H_(0ab31997,2d5213fa): case H_(bf875611,200e9990): /* vector_size */ 1119 case 6: case 7: /* vector_size */
1097 { 1120 {
1098 CTSize vsize = cp_decl_sizeattr(cp); 1121 CTSize vsize = cp_decl_sizeattr(cp);
1099 if (vsize) CTF_INSERT(decl->attr, VSIZEP, lj_fls(vsize)); 1122 if (vsize) CTF_INSERT(decl->attr, VSIZEP, lj_fls(vsize));
1100 } 1123 }
1101 break; 1124 break;
1102#if LJ_TARGET_X86 1125#if LJ_TARGET_X86
1103 case H_(5ad22db8,c689b848): case H_(439150fa,65ea78cb): /* regparm */ 1126 case 8: case 9: /* regparm */
1104 CTF_INSERT(decl->fattr, REGPARM, cp_decl_sizeattr(cp)); 1127 CTF_INSERT(decl->fattr, REGPARM, cp_decl_sizeattr(cp));
1105 decl->fattr |= CTFP_CCONV; 1128 decl->fattr |= CTFP_CCONV;
1106 break; 1129 break;
1107 case H_(18fc0b98,7ff4c074): case H_(4e62abed,0a747424): /* cdecl */ 1130 case 10: case 11: /* cdecl */
1108 CTF_INSERT(decl->fattr, CCONV, CTCC_CDECL); 1131 CTF_INSERT(decl->fattr, CCONV, CTCC_CDECL);
1109 decl->fattr |= CTFP_CCONV; 1132 decl->fattr |= CTFP_CCONV;
1110 break; 1133 break;
1111 case H_(72b2e41b,494c5a44): case H_(f2356d59,f25fc9bd): /* thiscall */ 1134 case 12: case 13: /* thiscall */
1112 CTF_INSERT(decl->fattr, CCONV, CTCC_THISCALL); 1135 CTF_INSERT(decl->fattr, CCONV, CTCC_THISCALL);
1113 decl->fattr |= CTFP_CCONV; 1136 decl->fattr |= CTFP_CCONV;
1114 break; 1137 break;
1115 case H_(0d0ffc42,ab746f88): case H_(21c54ba1,7f0ca7e3): /* fastcall */ 1138 case 14: case 15: /* fastcall */
1116 CTF_INSERT(decl->fattr, CCONV, CTCC_FASTCALL); 1139 CTF_INSERT(decl->fattr, CCONV, CTCC_FASTCALL);
1117 decl->fattr |= CTFP_CCONV; 1140 decl->fattr |= CTFP_CCONV;
1118 break; 1141 break;
1119 case H_(ef76b040,9412e06a): case H_(de56697b,c750e6e1): /* stdcall */ 1142 case 16: case 17: /* stdcall */
1120 CTF_INSERT(decl->fattr, CCONV, CTCC_STDCALL); 1143 CTF_INSERT(decl->fattr, CCONV, CTCC_STDCALL);
1121 decl->fattr |= CTFP_CCONV; 1144 decl->fattr |= CTFP_CCONV;
1122 break; 1145 break;
1123 case H_(ea78b622,f234bd8e): case H_(252ffb06,8d50f34b): /* sseregparm */ 1146 case 18: case 19: /* sseregparm */
1124 decl->fattr |= CTF_SSEREGPARM; 1147 decl->fattr |= CTF_SSEREGPARM;
1125 decl->fattr |= CTFP_CCONV; 1148 decl->fattr |= CTFP_CCONV;
1126 break; 1149 break;
@@ -1152,16 +1175,13 @@ static void cp_decl_msvcattribute(CPState *cp, CPDecl *decl)
1152 while (cp->tok == CTOK_IDENT) { 1175 while (cp->tok == CTOK_IDENT) {
1153 GCstr *attrstr = cp->str; 1176 GCstr *attrstr = cp->str;
1154 cp_next(cp); 1177 cp_next(cp);
1155 switch (attrstr->hash) { 1178 if (cp_str_is(attrstr, "align")) {
1156 case H_(bc2395fa,98f267f8): /* align */
1157 cp_decl_align(cp, decl); 1179 cp_decl_align(cp, decl);
1158 break; 1180 } else { /* Ignore all other attributes. */
1159 default: /* Ignore all other attributes. */
1160 if (cp_opt(cp, '(')) { 1181 if (cp_opt(cp, '(')) {
1161 while (cp->tok != ')' && cp->tok != CTOK_EOF) cp_next(cp); 1182 while (cp->tok != ')' && cp->tok != CTOK_EOF) cp_next(cp);
1162 cp_check(cp, ')'); 1183 cp_check(cp, ')');
1163 } 1184 }
1164 break;
1165 } 1185 }
1166 } 1186 }
1167 cp_check(cp, ')'); 1187 cp_check(cp, ')');
@@ -1572,7 +1592,7 @@ end_decl:
1572 cp_errmsg(cp, cp->tok, LJ_ERR_FFI_DECLSPEC); 1592 cp_errmsg(cp, cp->tok, LJ_ERR_FFI_DECLSPEC);
1573 sz = sizeof(int); 1593 sz = sizeof(int);
1574 } 1594 }
1575 lua_assert(sz != 0); 1595 lj_assertCP(sz != 0, "basic ctype with zero size");
1576 info += CTALIGN(lj_fls(sz)); /* Use natural alignment. */ 1596 info += CTALIGN(lj_fls(sz)); /* Use natural alignment. */
1577 info += (decl->attr & CTF_QUAL); /* Merge qualifiers. */ 1597 info += (decl->attr & CTF_QUAL); /* Merge qualifiers. */
1578 cp_push(decl, info, sz); 1598 cp_push(decl, info, sz);
@@ -1741,17 +1761,16 @@ static CTypeID cp_decl_abstract(CPState *cp)
1741static void cp_pragma(CPState *cp, BCLine pragmaline) 1761static void cp_pragma(CPState *cp, BCLine pragmaline)
1742{ 1762{
1743 cp_next(cp); 1763 cp_next(cp);
1744 if (cp->tok == CTOK_IDENT && 1764 if (cp->tok == CTOK_IDENT && cp_str_is(cp->str, "pack")) {
1745 cp->str->hash == H_(e79b999f,42ca3e85)) { /* pack */
1746 cp_next(cp); 1765 cp_next(cp);
1747 cp_check(cp, '('); 1766 cp_check(cp, '(');
1748 if (cp->tok == CTOK_IDENT) { 1767 if (cp->tok == CTOK_IDENT) {
1749 if (cp->str->hash == H_(738e923c,a1b65954)) { /* push */ 1768 if (cp_str_is(cp->str, "push")) {
1750 if (cp->curpack < CPARSE_MAX_PACKSTACK) { 1769 if (cp->curpack < CPARSE_MAX_PACKSTACK) {
1751 cp->packstack[cp->curpack+1] = cp->packstack[cp->curpack]; 1770 cp->packstack[cp->curpack+1] = cp->packstack[cp->curpack];
1752 cp->curpack++; 1771 cp->curpack++;
1753 } 1772 }
1754 } else if (cp->str->hash == H_(6c71cf27,6c71cf27)) { /* pop */ 1773 } else if (cp_str_is(cp->str, "pop")) {
1755 if (cp->curpack > 0) cp->curpack--; 1774 if (cp->curpack > 0) cp->curpack--;
1756 } else { 1775 } else {
1757 cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL); 1776 cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL);
@@ -1773,6 +1792,16 @@ static void cp_pragma(CPState *cp, BCLine pragmaline)
1773 } 1792 }
1774} 1793}
1775 1794
1795/* Handle line number. */
1796static void cp_line(CPState *cp, BCLine hashline)
1797{
1798 BCLine newline = cp->val.u32;
1799 /* TODO: Handle file name and include it in error messages. */
1800 while (cp->tok != CTOK_EOF && cp->linenumber == hashline)
1801 cp_next(cp);
1802 cp->linenumber = newline;
1803}
1804
1776/* Parse multiple C declarations of types or extern identifiers. */ 1805/* Parse multiple C declarations of types or extern identifiers. */
1777static void cp_decl_multi(CPState *cp) 1806static void cp_decl_multi(CPState *cp)
1778{ 1807{
@@ -1785,12 +1814,21 @@ static void cp_decl_multi(CPState *cp)
1785 continue; 1814 continue;
1786 } 1815 }
1787 if (cp->tok == '#') { /* Workaround, since we have no preprocessor, yet. */ 1816 if (cp->tok == '#') { /* Workaround, since we have no preprocessor, yet. */
1788 BCLine pragmaline = cp->linenumber; 1817 BCLine hashline = cp->linenumber;
1789 if (!(cp_next(cp) == CTOK_IDENT && 1818 CPToken tok = cp_next(cp);
1790 cp->str->hash == H_(f5e6b4f8,1d509107))) /* pragma */ 1819 if (tok == CTOK_INTEGER) {
1820 cp_line(cp, hashline);
1821 continue;
1822 } else if (tok == CTOK_IDENT && cp_str_is(cp->str, "line")) {
1823 if (cp_next(cp) != CTOK_INTEGER) cp_err_token(cp, tok);
1824 cp_line(cp, hashline);
1825 continue;
1826 } else if (tok == CTOK_IDENT && cp_str_is(cp->str, "pragma")) {
1827 cp_pragma(cp, hashline);
1828 continue;
1829 } else {
1791 cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL); 1830 cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL);
1792 cp_pragma(cp, pragmaline); 1831 }
1793 continue;
1794 } 1832 }
1795 scl = cp_decl_spec(cp, &decl, CDF_TYPEDEF|CDF_EXTERN|CDF_STATIC); 1833 scl = cp_decl_spec(cp, &decl, CDF_TYPEDEF|CDF_EXTERN|CDF_STATIC);
1796 if ((cp->tok == ';' || cp->tok == CTOK_EOF) && 1834 if ((cp->tok == ';' || cp->tok == CTOK_EOF) &&
@@ -1814,7 +1852,7 @@ static void cp_decl_multi(CPState *cp)
1814 /* Treat both static and extern function declarations as extern. */ 1852 /* Treat both static and extern function declarations as extern. */
1815 ct = ctype_get(cp->cts, ctypeid); 1853 ct = ctype_get(cp->cts, ctypeid);
1816 /* We always get new anonymous functions (typedefs are copied). */ 1854 /* We always get new anonymous functions (typedefs are copied). */
1817 lua_assert(gcref(ct->name) == NULL); 1855 lj_assertCP(gcref(ct->name) == NULL, "unexpected named function");
1818 id = ctypeid; /* Just name it. */ 1856 id = ctypeid; /* Just name it. */
1819 } else if ((scl & CDF_STATIC)) { /* Accept static constants. */ 1857 } else if ((scl & CDF_STATIC)) { /* Accept static constants. */
1820 id = cp_decl_constinit(cp, &ct, ctypeid); 1858 id = cp_decl_constinit(cp, &ct, ctypeid);
@@ -1856,8 +1894,6 @@ static void cp_decl_single(CPState *cp)
1856 if (cp->tok != CTOK_EOF) cp_err_token(cp, CTOK_EOF); 1894 if (cp->tok != CTOK_EOF) cp_err_token(cp, CTOK_EOF);
1857} 1895}
1858 1896
1859#undef H_
1860
1861/* ------------------------------------------------------------------------ */ 1897/* ------------------------------------------------------------------------ */
1862 1898
1863/* Protected callback for C parser. */ 1899/* Protected callback for C parser. */
@@ -1873,7 +1909,7 @@ static TValue *cpcparser(lua_State *L, lua_CFunction dummy, void *ud)
1873 cp_decl_single(cp); 1909 cp_decl_single(cp);
1874 if (cp->param && cp->param != cp->L->top) 1910 if (cp->param && cp->param != cp->L->top)
1875 cp_err(cp, LJ_ERR_FFI_NUMPARAM); 1911 cp_err(cp, LJ_ERR_FFI_NUMPARAM);
1876 lua_assert(cp->depth == 0); 1912 lj_assertCP(cp->depth == 0, "unbalanced cparser declaration depth");
1877 return NULL; 1913 return NULL;
1878} 1914}
1879 1915