aboutsummaryrefslogtreecommitdiff
path: root/src/lj_parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_parse.c')
-rw-r--r--src/lj_parse.c226
1 files changed, 167 insertions, 59 deletions
diff --git a/src/lj_parse.c b/src/lj_parse.c
index 992034eb..bd9d9a7a 100644
--- a/src/lj_parse.c
+++ b/src/lj_parse.c
@@ -12,6 +12,7 @@
12#include "lj_obj.h" 12#include "lj_obj.h"
13#include "lj_gc.h" 13#include "lj_gc.h"
14#include "lj_err.h" 14#include "lj_err.h"
15#include "lj_debug.h"
15#include "lj_str.h" 16#include "lj_str.h"
16#include "lj_tab.h" 17#include "lj_tab.h"
17#include "lj_func.h" 18#include "lj_func.h"
@@ -1021,7 +1022,8 @@ static void var_new(LexState *ls, BCReg n, GCstr *name)
1021 lj_lex_error(ls, 0, LJ_ERR_XLIMC, LJ_MAX_VSTACK); 1022 lj_lex_error(ls, 0, LJ_ERR_XLIMC, LJ_MAX_VSTACK);
1022 lj_mem_growvec(ls->L, ls->vstack, ls->sizevstack, LJ_MAX_VSTACK, VarInfo); 1023 lj_mem_growvec(ls->L, ls->vstack, ls->sizevstack, LJ_MAX_VSTACK, VarInfo);
1023 } 1024 }
1024 lua_assert(lj_tab_getstr(fs->kt, name) != NULL); 1025 lua_assert((uintptr_t)name < VARNAME__MAX ||
1026 lj_tab_getstr(fs->kt, name) != NULL);
1025 /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */ 1027 /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */
1026 setgcref(ls->vstack[vtop].name, obj2gco(name)); 1028 setgcref(ls->vstack[vtop].name, obj2gco(name));
1027 fs->varmap[fs->nactvar+n] = (uint16_t)vtop; 1029 fs->varmap[fs->nactvar+n] = (uint16_t)vtop;
@@ -1031,6 +1033,9 @@ static void var_new(LexState *ls, BCReg n, GCstr *name)
1031#define var_new_lit(ls, n, v) \ 1033#define var_new_lit(ls, n, v) \
1032 var_new(ls, (n), lj_parse_keepstr(ls, "" v, sizeof(v)-1)) 1034 var_new(ls, (n), lj_parse_keepstr(ls, "" v, sizeof(v)-1))
1033 1035
1036#define var_new_fixed(ls, n, vn) \
1037 var_new(ls, (n), (GCstr *)(uintptr_t)(vn))
1038
1034/* Add local variables. */ 1039/* Add local variables. */
1035static void var_add(LexState *ls, BCReg nvars) 1040static void var_add(LexState *ls, BCReg nvars)
1036{ 1041{
@@ -1053,7 +1058,7 @@ static BCReg var_lookup_local(FuncState *fs, GCstr *n)
1053{ 1058{
1054 int i; 1059 int i;
1055 for (i = fs->nactvar-1; i >= 0; i--) { 1060 for (i = fs->nactvar-1; i >= 0; i--) {
1056 if (n == gco2str(gcref(var_get(fs->ls, fs, i).name))) 1061 if (n == strref(var_get(fs->ls, fs, i).name))
1057 return (BCReg)i; 1062 return (BCReg)i;
1058 } 1063 }
1059 return (BCReg)-1; /* Not found. */ 1064 return (BCReg)-1; /* Not found. */
@@ -1109,23 +1114,16 @@ static MSize var_lookup_(FuncState *fs, GCstr *name, ExpDesc *e, int first)
1109 1114
1110/* -- Function state management ------------------------------------------- */ 1115/* -- Function state management ------------------------------------------- */
1111 1116
1112/* NYI: compress debug info. */ 1117/* Fixup bytecode for prototype. */
1113 1118static void fs_fixup_bc(FuncState *fs, GCproto *pt, BCIns *bc, MSize n)
1114/* Fixup bytecode and lineinfo for prototype. */
1115static void fs_fixup_bc(FuncState *fs, GCproto *pt, BCIns *bc, BCLine *lineinfo)
1116{ 1119{
1117 MSize i, n = fs->pc;
1118 BCInsLine *base = fs->bcbase; 1120 BCInsLine *base = fs->bcbase;
1119 setmref(pt->lineinfo, lineinfo); 1121 MSize i;
1120 pt->sizebc = n; 1122 pt->sizebc = n;
1121 bc[n] = ~0u; /* Close potentially uninitialized gap between bc and kgc. */
1122 bc[0] = BCINS_AD((fs->flags & PROTO_IS_VARARG) ? BC_FUNCV : BC_FUNCF, 1123 bc[0] = BCINS_AD((fs->flags & PROTO_IS_VARARG) ? BC_FUNCV : BC_FUNCF,
1123 fs->framesize, 0); 1124 fs->framesize, 0);
1124 lineinfo[0] = fs->linedefined; 1125 for (i = 1; i < n; i++)
1125 for (i = 1; i < n; i++) {
1126 bc[i] = base[i].ins; 1126 bc[i] = base[i].ins;
1127 lineinfo[i] = base[i].line;
1128 }
1129} 1127}
1130 1128
1131/* Fixup constants for prototype. */ 1129/* Fixup constants for prototype. */
@@ -1189,20 +1187,138 @@ static void fs_fixup_uv(FuncState *fs, GCproto *pt, uint16_t *uv)
1189 uv[i] = fs->uvloc[i].slot; 1187 uv[i] = fs->uvloc[i].slot;
1190} 1188}
1191 1189
1192/* Fixup debug info for prototype. */ 1190#ifndef LUAJIT_DISABLE_DEBUGINFO
1193static void fs_fixup_dbg(FuncState *fs, GCproto *pt, VarInfo *vi, MSize sizevi) 1191/* Prepare lineinfo for prototype. */
1192static size_t fs_prep_line(FuncState *fs, BCLine numline)
1193{
1194 return (fs->pc-1) << (numline < 256 ? 0 : numline < 65536 ? 1 : 2);
1195}
1196
1197/* Fixup lineinfo for prototype. */
1198static void fs_fixup_line(FuncState *fs, GCproto *pt,
1199 void *lineinfo, BCLine numline)
1200{
1201 BCInsLine *base = fs->bcbase + 1;
1202 BCLine first = fs->linedefined;
1203 MSize i = 0, n = fs->pc-1;
1204 pt->firstline = fs->linedefined;
1205 pt->numline = numline;
1206 setmref(pt->lineinfo, lineinfo);
1207 if (LJ_LIKELY(numline < 256)) {
1208 uint8_t *li = (uint8_t *)lineinfo;
1209 do {
1210 BCLine delta = base[i].line - first;
1211 lua_assert(delta >= 0 && delta < 256);
1212 li[i] = (uint8_t)delta;
1213 } while (++i < n);
1214 } else if (LJ_LIKELY(numline < 65536)) {
1215 uint16_t *li = (uint16_t *)lineinfo;
1216 do {
1217 BCLine delta = base[i].line - first;
1218 lua_assert(delta >= 0 && delta < 65536);
1219 li[i] = (uint16_t)delta;
1220 } while (++i < n);
1221 } else {
1222 uint32_t *li = (uint32_t *)lineinfo;
1223 do {
1224 BCLine delta = base[i].line - first;
1225 lua_assert(delta >= 0);
1226 li[i] = (uint32_t)delta;
1227 } while (++i < n);
1228 }
1229}
1230
1231/* Resize buffer if needed. */
1232static LJ_NOINLINE void fs_buf_resize(LexState *ls, MSize len)
1233{
1234 MSize sz = ls->sb.sz * 2;
1235 while (ls->sb.n + len > sz) sz = sz * 2;
1236 lj_str_resizebuf(ls->L, &ls->sb, sz);
1237}
1238
1239static LJ_AINLINE void fs_buf_need(LexState *ls, MSize len)
1240{
1241 if (LJ_UNLIKELY(ls->sb.n + len > ls->sb.sz))
1242 fs_buf_resize(ls, len);
1243}
1244
1245/* Add string to buffer. */
1246static void fs_buf_str(LexState *ls, const char *str, MSize len)
1247{
1248 char *p = ls->sb.buf + ls->sb.n;
1249 MSize i;
1250 ls->sb.n += len;
1251 for (i = 0; i < len; i++) p[i] = str[i];
1252}
1253
1254/* Add ULEB128 value to buffer. */
1255static void fs_buf_uleb128(LexState *ls, uint32_t v)
1256{
1257 MSize n = ls->sb.n;
1258 uint8_t *p = (uint8_t *)ls->sb.buf;
1259 for (; v >= 0x80; v >>= 7)
1260 p[n++] = (uint8_t)((v & 0x7f) | 0x80);
1261 p[n++] = (uint8_t)v;
1262 ls->sb.n = n;
1263}
1264
1265/* Prepare variable info for prototype. */
1266static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar)
1194{ 1267{
1195 MSize i, n = fs->nuv;
1196 GCRef *uvname = (GCRef *)((char *)vi + sizevi*sizeof(VarInfo));
1197 VarInfo *vstack = fs->ls->vstack; 1268 VarInfo *vstack = fs->ls->vstack;
1198 setmref(pt->varinfo, vi); 1269 MSize i, n;
1199 setmref(pt->uvname, uvname); 1270 BCPos lastpc;
1200 pt->sizevarinfo = sizevi; 1271 lj_str_resetbuf(&ls->sb); /* Copy to temp. string buffer. */
1201 memcpy(vi, &vstack[fs->vbase], sizevi*sizeof(VarInfo)); 1272 /* Store upvalue names. */
1202 for (i = 0; i < n; i++) 1273 for (i = 0, n = fs->nuv; i < n; i++) {
1203 setgcref(uvname[i], gcref(vstack[fs->uvloc[i].vidx].name)); 1274 GCstr *s = strref(vstack[fs->uvloc[i].vidx].name);
1275 MSize len = s->len+1;
1276 fs_buf_need(ls, len);
1277 fs_buf_str(ls, strdata(s), len);
1278 }
1279 *ofsvar = ls->sb.n;
1280 vstack += fs->vbase;
1281 lastpc = 0;
1282 /* Store local variable names and compressed ranges. */
1283 for (i = 0, n = ls->vtop - fs->vbase; i < n; i++) {
1284 GCstr *s = strref(vstack[i].name);
1285 BCPos startpc = vstack[i].startpc, endpc = vstack[i].endpc;
1286 if ((uintptr_t)s < VARNAME__MAX) {
1287 fs_buf_need(ls, 1 + 2*5);
1288 ls->sb.buf[ls->sb.n++] = (uint8_t)(uintptr_t)s;
1289 } else {
1290 MSize len = s->len+1;
1291 fs_buf_need(ls, len + 2*5);
1292 fs_buf_str(ls, strdata(s), len);
1293 }
1294 fs_buf_uleb128(ls, startpc-lastpc);
1295 fs_buf_uleb128(ls, endpc-startpc);
1296 lastpc = startpc;
1297 }
1298 fs_buf_need(ls, 1);
1299 ls->sb.buf[ls->sb.n++] = '\0'; /* Terminator for varinfo. */
1300 return ls->sb.n;
1204} 1301}
1205 1302
1303/* Fixup variable info for prototype. */
1304static void fs_fixup_var(LexState *ls, GCproto *pt, uint8_t *p, size_t ofsvar)
1305{
1306 setmref(pt->uvinfo, p);
1307 setmref(pt->varinfo, (char *)p + ofsvar);
1308 memcpy(p, ls->sb.buf, ls->sb.n); /* Copy from temp. string buffer. */
1309}
1310#else
1311
1312/* Initialize with empty debug info, if disabled. */
1313#define fs_prep_line(fs, numline) (UNUSED(numline), 0)
1314#define fs_fixup_line(fs, pt, li, numline) \
1315 pt->firstline = pt->numline = 0, setmref((pt)->lineinfo, NULL)
1316#define fs_prep_var(ls, fs, ofsvar) (UNUSED(ofsvar), 0)
1317#define fs_fixup_var(ls, pt, p, ofsvar) \
1318 setmref((pt)->uvinfo, NULL), setmref((pt)->varinfo, NULL)
1319
1320#endif
1321
1206/* Check if bytecode op returns. */ 1322/* Check if bytecode op returns. */
1207static int bcopisret(BCOp op) 1323static int bcopisret(BCOp op)
1208{ 1324{
@@ -1253,8 +1369,8 @@ static GCproto *fs_finish(LexState *ls, BCLine line)
1253{ 1369{
1254 lua_State *L = ls->L; 1370 lua_State *L = ls->L;
1255 FuncState *fs = ls->fs; 1371 FuncState *fs = ls->fs;
1256 MSize sizevi; 1372 BCLine numline = line - fs->linedefined;
1257 size_t sizept, ofsk, ofsuv, ofsdbg, ofsli; 1373 size_t sizept, ofsk, ofsuv, ofsli, ofsdbg, ofsvar;
1258 GCproto *pt; 1374 GCproto *pt;
1259 1375
1260 /* Apply final fixups. */ 1376 /* Apply final fixups. */
@@ -1264,33 +1380,29 @@ static GCproto *fs_finish(LexState *ls, BCLine line)
1264 1380
1265 /* Calculate total size of prototype including all colocated arrays. */ 1381 /* Calculate total size of prototype including all colocated arrays. */
1266 sizept = sizeof(GCproto) + fs->pc*sizeof(BCIns) + fs->nkgc*sizeof(GCRef); 1382 sizept = sizeof(GCproto) + fs->pc*sizeof(BCIns) + fs->nkgc*sizeof(GCRef);
1267 sizept = (sizept + sizeof(lua_Number)-1) & ~(sizeof(lua_Number)-1); 1383 sizept = (sizept + sizeof(TValue)-1) & ~(sizeof(TValue)-1);
1268 ofsk = sizept; 1384 ofsk = sizept; sizept += fs->nkn*sizeof(TValue);
1269 sizept += fs->nkn*sizeof(lua_Number); 1385 ofsuv = sizept; sizept += ((fs->nuv+1)&~1)*2;
1270 ofsuv = sizept; 1386 ofsli = sizept; sizept += fs_prep_line(fs, numline);
1271 sizept += ((fs->nuv+1)&~1)*2; 1387 ofsdbg = sizept; sizept += fs_prep_var(ls, fs, &ofsvar);
1272 ofsdbg = sizept;
1273 sizevi = ls->vtop - fs->vbase;
1274 sizept += sizevi*sizeof(VarInfo) + fs->nuv*sizeof(GCRef);
1275 ofsli = sizept;
1276 sizept += fs->pc*sizeof(BCLine);
1277 1388
1278 /* Allocate prototype and initialize its fields. */ 1389 /* Allocate prototype and initialize its fields. */
1279 pt = (GCproto *)lj_mem_newgco(L, (MSize)sizept); 1390 pt = (GCproto *)lj_mem_newgco(L, (MSize)sizept);
1280 pt->gct = ~LJ_TPROTO; 1391 pt->gct = ~LJ_TPROTO;
1281 pt->sizept = (MSize)sizept; 1392 pt->sizept = (MSize)sizept;
1282 setgcref(pt->chunkname, obj2gco(ls->chunkname));
1283 pt->trace = 0; 1393 pt->trace = 0;
1284 pt->flags = fs->flags; 1394 pt->flags = fs->flags;
1285 pt->numparams = fs->numparams; 1395 pt->numparams = fs->numparams;
1286 pt->framesize = fs->framesize; 1396 pt->framesize = fs->framesize;
1287 pt->lastlinedefined = line; 1397 setgcref(pt->chunkname, obj2gco(ls->chunkname));
1288 1398
1289 fs_fixup_bc(fs, pt, (BCIns *)((char *)pt + sizeof(GCproto)), 1399 /* Close potentially uninitialized gap between bc and kgc. */
1290 (BCLine *)((char *)pt + ofsli)); 1400 *(uint32_t *)((char *)pt + ofsk - sizeof(GCRef)*(fs->nkgc+1)) = 0;
1401 fs_fixup_bc(fs, pt, (BCIns *)((char *)pt + sizeof(GCproto)), fs->pc);
1291 fs_fixup_k(fs, pt, (void *)((char *)pt + ofsk)); 1402 fs_fixup_k(fs, pt, (void *)((char *)pt + ofsk));
1292 fs_fixup_uv(fs, pt, (uint16_t *)((char *)pt + ofsuv)); 1403 fs_fixup_uv(fs, pt, (uint16_t *)((char *)pt + ofsuv));
1293 fs_fixup_dbg(fs, pt, (VarInfo *)((char *)pt + ofsdbg), sizevi); 1404 fs_fixup_line(fs, pt, (void *)((char *)pt + ofsli), numline);
1405 fs_fixup_var(ls, pt, (uint8_t *)((char *)pt + ofsdbg), ofsvar);
1294 1406
1295 lj_vmevent_send(L, BC, 1407 lj_vmevent_send(L, BC,
1296 setprotoV(L, L->top++, pt); 1408 setprotoV(L, L->top++, pt);
@@ -1300,12 +1412,6 @@ static GCproto *fs_finish(LexState *ls, BCLine line)
1300 ls->vtop = fs->vbase; /* Reset variable stack. */ 1412 ls->vtop = fs->vbase; /* Reset variable stack. */
1301 ls->fs = fs->prev; 1413 ls->fs = fs->prev;
1302 lua_assert(ls->fs != NULL || ls->token == TK_eof); 1414 lua_assert(ls->fs != NULL || ls->token == TK_eof);
1303 /* Re-anchor last string token to avoid GC. */
1304 if (ls->token == TK_name || ls->token == TK_string) {
1305 /* NOBARRIER: the key is new or kept alive. */
1306 TValue *tv = lj_tab_setstr(ls->L, ls->fs->kt, strV(&ls->tokenval));
1307 if (tvisnil(tv)) setboolV(tv, 1);
1308 }
1309 return pt; 1415 return pt;
1310} 1416}
1311 1417
@@ -1530,8 +1636,6 @@ static void parse_chunk(LexState *ls);
1530static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line) 1636static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line)
1531{ 1637{
1532 FuncState fs, *pfs = ls->fs; 1638 FuncState fs, *pfs = ls->fs;
1533 BCReg kidx;
1534 BCLine lastline;
1535 GCproto *pt; 1639 GCproto *pt;
1536 ptrdiff_t oldbase = pfs->bcbase - ls->bcstack; 1640 ptrdiff_t oldbase = pfs->bcbase - ls->bcstack;
1537 fs_init(ls, &fs); 1641 fs_init(ls, &fs);
@@ -1541,19 +1645,19 @@ static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line)
1541 fs.bclim = pfs->bclim - pfs->pc; 1645 fs.bclim = pfs->bclim - pfs->pc;
1542 bcemit_AD(&fs, BC_FUNCF, 0, 0); /* Placeholder. */ 1646 bcemit_AD(&fs, BC_FUNCF, 0, 0); /* Placeholder. */
1543 parse_chunk(ls); 1647 parse_chunk(ls);
1544 lastline = ls->linenumber; 1648 if (ls->token != TK_end) lex_match(ls, TK_end, TK_function, line);
1545 lex_match(ls, TK_end, TK_function, line); 1649 pt = fs_finish(ls, (ls->lastline = ls->linenumber));
1546 pt = fs_finish(ls, lastline);
1547 pfs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */ 1650 pfs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */
1548 pfs->bclim = (BCPos)(ls->sizebcstack - oldbase); 1651 pfs->bclim = (BCPos)(ls->sizebcstack - oldbase);
1549 /* Store new prototype in the constant array of the parent. */ 1652 /* Store new prototype in the constant array of the parent. */
1550 kidx = const_gc(pfs, obj2gco(pt), LJ_TPROTO); 1653 expr_init(e, VRELOCABLE,
1551 expr_init(e, VRELOCABLE, bcemit_AD(pfs, BC_FNEW, 0, kidx)); 1654 bcemit_AD(pfs, BC_FNEW, 0, const_gc(pfs, obj2gco(pt), LJ_TPROTO)));
1552 if (!(pfs->flags & PROTO_HAS_FNEW)) { 1655 if (!(pfs->flags & PROTO_HAS_FNEW)) {
1553 if (pfs->flags & PROTO_HAS_RETURN) 1656 if (pfs->flags & PROTO_HAS_RETURN)
1554 pfs->flags |= PROTO_FIXUP_RETURN; 1657 pfs->flags |= PROTO_FIXUP_RETURN;
1555 pfs->flags |= PROTO_HAS_FNEW; 1658 pfs->flags |= PROTO_HAS_FNEW;
1556 } 1659 }
1660 lj_lex_next(ls);
1557} 1661}
1558 1662
1559/* Parse expression list. Last expression is left open. */ 1663/* Parse expression list. Last expression is left open. */
@@ -2146,9 +2250,9 @@ static void parse_for_num(LexState *ls, GCstr *varname, BCLine line)
2146 FuncScope bl; 2250 FuncScope bl;
2147 BCPos loop, loopend; 2251 BCPos loop, loopend;
2148 /* Hidden control variables. */ 2252 /* Hidden control variables. */
2149 var_new_lit(ls, FORL_IDX, "(for index)"); 2253 var_new_fixed(ls, FORL_IDX, VARNAME_FOR_IDX);
2150 var_new_lit(ls, FORL_STOP, "(for limit)"); 2254 var_new_fixed(ls, FORL_STOP, VARNAME_FOR_STOP);
2151 var_new_lit(ls, FORL_STEP, "(for step)"); 2255 var_new_fixed(ls, FORL_STEP, VARNAME_FOR_STEP);
2152 /* Visible copy of index variable. */ 2256 /* Visible copy of index variable. */
2153 var_new(ls, FORL_EXT, varname); 2257 var_new(ls, FORL_EXT, varname);
2154 lex_check(ls, '='); 2258 lex_check(ls, '=');
@@ -2220,9 +2324,9 @@ static void parse_for_iter(LexState *ls, GCstr *indexname)
2220 FuncScope bl; 2324 FuncScope bl;
2221 int isnext; 2325 int isnext;
2222 /* Hidden control variables. */ 2326 /* Hidden control variables. */
2223 var_new_lit(ls, nvars++, "(for generator)"); 2327 var_new_fixed(ls, nvars++, VARNAME_FOR_GEN);
2224 var_new_lit(ls, nvars++, "(for state)"); 2328 var_new_fixed(ls, nvars++, VARNAME_FOR_STATE);
2225 var_new_lit(ls, nvars++, "(for control)"); 2329 var_new_fixed(ls, nvars++, VARNAME_FOR_CTL);
2226 /* Visible variables returned from iterator. */ 2330 /* Visible variables returned from iterator. */
2227 var_new(ls, nvars++, indexname); 2331 var_new(ls, nvars++, indexname);
2228 while (lex_opt(ls, ',')) 2332 while (lex_opt(ls, ','))
@@ -2374,7 +2478,11 @@ GCproto *lj_parse(LexState *ls)
2374 FuncState fs; 2478 FuncState fs;
2375 GCproto *pt; 2479 GCproto *pt;
2376 lua_State *L = ls->L; 2480 lua_State *L = ls->L;
2481#ifdef LUAJIT_DISABLE_DEBUGINFO
2482 ls->chunkname = lj_str_newlit(L, "=");
2483#else
2377 ls->chunkname = lj_str_newz(L, ls->chunkarg); 2484 ls->chunkname = lj_str_newz(L, ls->chunkarg);
2485#endif
2378 setstrV(L, L->top, ls->chunkname); /* Anchor chunkname string. */ 2486 setstrV(L, L->top, ls->chunkname); /* Anchor chunkname string. */
2379 incr_top(L); 2487 incr_top(L);
2380 ls->level = 0; 2488 ls->level = 0;