diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_parse.c | 189 |
1 files changed, 80 insertions, 109 deletions
diff --git a/src/lj_parse.c b/src/lj_parse.c index 2a601f1d..610c8614 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c | |||
@@ -13,6 +13,7 @@ | |||
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_debug.h" |
16 | #include "lj_buf.h" | ||
16 | #include "lj_str.h" | 17 | #include "lj_str.h" |
17 | #include "lj_tab.h" | 18 | #include "lj_tab.h" |
18 | #include "lj_func.h" | 19 | #include "lj_func.h" |
@@ -21,6 +22,7 @@ | |||
21 | #if LJ_HASFFI | 22 | #if LJ_HASFFI |
22 | #include "lj_ctype.h" | 23 | #include "lj_ctype.h" |
23 | #endif | 24 | #endif |
25 | #include "lj_strfmt.h" | ||
24 | #include "lj_lex.h" | 26 | #include "lj_lex.h" |
25 | #include "lj_parse.h" | 27 | #include "lj_parse.h" |
26 | #include "lj_vm.h" | 28 | #include "lj_vm.h" |
@@ -165,12 +167,12 @@ LJ_STATIC_ASSERT((int)BC_MODVV-(int)BC_ADDVV == (int)OPR_MOD-(int)OPR_ADD); | |||
165 | 167 | ||
166 | LJ_NORET LJ_NOINLINE static void err_syntax(LexState *ls, ErrMsg em) | 168 | LJ_NORET LJ_NOINLINE static void err_syntax(LexState *ls, ErrMsg em) |
167 | { | 169 | { |
168 | lj_lex_error(ls, ls->token, em); | 170 | lj_lex_error(ls, ls->tok, em); |
169 | } | 171 | } |
170 | 172 | ||
171 | LJ_NORET LJ_NOINLINE static void err_token(LexState *ls, LexToken token) | 173 | LJ_NORET LJ_NOINLINE static void err_token(LexState *ls, LexToken tok) |
172 | { | 174 | { |
173 | lj_lex_error(ls, ls->token, LJ_ERR_XTOKEN, lj_lex_token2str(ls, token)); | 175 | lj_lex_error(ls, ls->tok, LJ_ERR_XTOKEN, lj_lex_token2str(ls, tok)); |
174 | } | 176 | } |
175 | 177 | ||
176 | LJ_NORET static void err_limit(FuncState *fs, uint32_t limit, const char *what) | 178 | LJ_NORET static void err_limit(FuncState *fs, uint32_t limit, const char *what) |
@@ -660,16 +662,16 @@ static void bcemit_method(FuncState *fs, ExpDesc *e, ExpDesc *key) | |||
660 | BCReg idx, func, obj = expr_toanyreg(fs, e); | 662 | BCReg idx, func, obj = expr_toanyreg(fs, e); |
661 | expr_free(fs, e); | 663 | expr_free(fs, e); |
662 | func = fs->freereg; | 664 | func = fs->freereg; |
663 | bcemit_AD(fs, BC_MOV, func+1, obj); /* Copy object to first argument. */ | 665 | bcemit_AD(fs, BC_MOV, func+1+LJ_FR2, obj); /* Copy object to 1st argument. */ |
664 | lua_assert(expr_isstrk(key)); | 666 | lua_assert(expr_isstrk(key)); |
665 | idx = const_str(fs, key); | 667 | idx = const_str(fs, key); |
666 | if (idx <= BCMAX_C) { | 668 | if (idx <= BCMAX_C) { |
667 | bcreg_reserve(fs, 2); | 669 | bcreg_reserve(fs, 2+LJ_FR2); |
668 | bcemit_ABC(fs, BC_TGETS, func, obj, idx); | 670 | bcemit_ABC(fs, BC_TGETS, func, obj, idx); |
669 | } else { | 671 | } else { |
670 | bcreg_reserve(fs, 3); | 672 | bcreg_reserve(fs, 3+LJ_FR2); |
671 | bcemit_AD(fs, BC_KSTR, func+2, idx); | 673 | bcemit_AD(fs, BC_KSTR, func+2+LJ_FR2, idx); |
672 | bcemit_ABC(fs, BC_TGETV, func, obj, func+2); | 674 | bcemit_ABC(fs, BC_TGETV, func, obj, func+2+LJ_FR2); |
673 | fs->freereg--; | 675 | fs->freereg--; |
674 | } | 676 | } |
675 | e->u.s.info = func; | 677 | e->u.s.info = func; |
@@ -983,7 +985,7 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e) | |||
983 | /* Check and consume optional token. */ | 985 | /* Check and consume optional token. */ |
984 | static int lex_opt(LexState *ls, LexToken tok) | 986 | static int lex_opt(LexState *ls, LexToken tok) |
985 | { | 987 | { |
986 | if (ls->token == tok) { | 988 | if (ls->tok == tok) { |
987 | lj_lex_next(ls); | 989 | lj_lex_next(ls); |
988 | return 1; | 990 | return 1; |
989 | } | 991 | } |
@@ -993,7 +995,7 @@ static int lex_opt(LexState *ls, LexToken tok) | |||
993 | /* Check and consume token. */ | 995 | /* Check and consume token. */ |
994 | static void lex_check(LexState *ls, LexToken tok) | 996 | static void lex_check(LexState *ls, LexToken tok) |
995 | { | 997 | { |
996 | if (ls->token != tok) | 998 | if (ls->tok != tok) |
997 | err_token(ls, tok); | 999 | err_token(ls, tok); |
998 | lj_lex_next(ls); | 1000 | lj_lex_next(ls); |
999 | } | 1001 | } |
@@ -1007,7 +1009,7 @@ static void lex_match(LexState *ls, LexToken what, LexToken who, BCLine line) | |||
1007 | } else { | 1009 | } else { |
1008 | const char *swhat = lj_lex_token2str(ls, what); | 1010 | const char *swhat = lj_lex_token2str(ls, what); |
1009 | const char *swho = lj_lex_token2str(ls, who); | 1011 | const char *swho = lj_lex_token2str(ls, who); |
1010 | lj_lex_error(ls, ls->token, LJ_ERR_XMATCH, swhat, swho, line); | 1012 | lj_lex_error(ls, ls->tok, LJ_ERR_XMATCH, swhat, swho, line); |
1011 | } | 1013 | } |
1012 | } | 1014 | } |
1013 | } | 1015 | } |
@@ -1016,9 +1018,9 @@ static void lex_match(LexState *ls, LexToken what, LexToken who, BCLine line) | |||
1016 | static GCstr *lex_str(LexState *ls) | 1018 | static GCstr *lex_str(LexState *ls) |
1017 | { | 1019 | { |
1018 | GCstr *s; | 1020 | GCstr *s; |
1019 | if (ls->token != TK_name && (LJ_52 || ls->token != TK_goto)) | 1021 | if (ls->tok != TK_name && (LJ_52 || ls->tok != TK_goto)) |
1020 | err_token(ls, TK_name); | 1022 | err_token(ls, TK_name); |
1021 | s = strV(&ls->tokenval); | 1023 | s = strV(&ls->tokval); |
1022 | lj_lex_next(ls); | 1024 | lj_lex_next(ls); |
1023 | return s; | 1025 | return s; |
1024 | } | 1026 | } |
@@ -1431,78 +1433,46 @@ static void fs_fixup_line(FuncState *fs, GCproto *pt, | |||
1431 | } | 1433 | } |
1432 | } | 1434 | } |
1433 | 1435 | ||
1434 | /* Resize buffer if needed. */ | ||
1435 | static LJ_NOINLINE void fs_buf_resize(LexState *ls, MSize len) | ||
1436 | { | ||
1437 | MSize sz = ls->sb.sz * 2; | ||
1438 | while (ls->sb.n + len > sz) sz = sz * 2; | ||
1439 | lj_str_resizebuf(ls->L, &ls->sb, sz); | ||
1440 | } | ||
1441 | |||
1442 | static LJ_AINLINE void fs_buf_need(LexState *ls, MSize len) | ||
1443 | { | ||
1444 | if (LJ_UNLIKELY(ls->sb.n + len > ls->sb.sz)) | ||
1445 | fs_buf_resize(ls, len); | ||
1446 | } | ||
1447 | |||
1448 | /* Add string to buffer. */ | ||
1449 | static void fs_buf_str(LexState *ls, const char *str, MSize len) | ||
1450 | { | ||
1451 | char *p = ls->sb.buf + ls->sb.n; | ||
1452 | MSize i; | ||
1453 | ls->sb.n += len; | ||
1454 | for (i = 0; i < len; i++) p[i] = str[i]; | ||
1455 | } | ||
1456 | |||
1457 | /* Add ULEB128 value to buffer. */ | ||
1458 | static void fs_buf_uleb128(LexState *ls, uint32_t v) | ||
1459 | { | ||
1460 | MSize n = ls->sb.n; | ||
1461 | uint8_t *p = (uint8_t *)ls->sb.buf; | ||
1462 | for (; v >= 0x80; v >>= 7) | ||
1463 | p[n++] = (uint8_t)((v & 0x7f) | 0x80); | ||
1464 | p[n++] = (uint8_t)v; | ||
1465 | ls->sb.n = n; | ||
1466 | } | ||
1467 | |||
1468 | /* Prepare variable info for prototype. */ | 1436 | /* Prepare variable info for prototype. */ |
1469 | static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar) | 1437 | static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar) |
1470 | { | 1438 | { |
1471 | VarInfo *vs =ls->vstack, *ve; | 1439 | VarInfo *vs =ls->vstack, *ve; |
1472 | MSize i, n; | 1440 | MSize i, n; |
1473 | BCPos lastpc; | 1441 | BCPos lastpc; |
1474 | lj_str_resetbuf(&ls->sb); /* Copy to temp. string buffer. */ | 1442 | lj_buf_reset(&ls->sb); /* Copy to temp. string buffer. */ |
1475 | /* Store upvalue names. */ | 1443 | /* Store upvalue names. */ |
1476 | for (i = 0, n = fs->nuv; i < n; i++) { | 1444 | for (i = 0, n = fs->nuv; i < n; i++) { |
1477 | GCstr *s = strref(vs[fs->uvmap[i]].name); | 1445 | GCstr *s = strref(vs[fs->uvmap[i]].name); |
1478 | MSize len = s->len+1; | 1446 | MSize len = s->len+1; |
1479 | fs_buf_need(ls, len); | 1447 | char *p = lj_buf_more(&ls->sb, len); |
1480 | fs_buf_str(ls, strdata(s), len); | 1448 | p = lj_buf_wmem(p, strdata(s), len); |
1449 | setsbufP(&ls->sb, p); | ||
1481 | } | 1450 | } |
1482 | *ofsvar = ls->sb.n; | 1451 | *ofsvar = sbuflen(&ls->sb); |
1483 | lastpc = 0; | 1452 | lastpc = 0; |
1484 | /* Store local variable names and compressed ranges. */ | 1453 | /* Store local variable names and compressed ranges. */ |
1485 | for (ve = vs + ls->vtop, vs += fs->vbase; vs < ve; vs++) { | 1454 | for (ve = vs + ls->vtop, vs += fs->vbase; vs < ve; vs++) { |
1486 | if (!gola_isgotolabel(vs)) { | 1455 | if (!gola_isgotolabel(vs)) { |
1487 | GCstr *s = strref(vs->name); | 1456 | GCstr *s = strref(vs->name); |
1488 | BCPos startpc; | 1457 | BCPos startpc; |
1458 | char *p; | ||
1489 | if ((uintptr_t)s < VARNAME__MAX) { | 1459 | if ((uintptr_t)s < VARNAME__MAX) { |
1490 | fs_buf_need(ls, 1 + 2*5); | 1460 | p = lj_buf_more(&ls->sb, 1 + 2*5); |
1491 | ls->sb.buf[ls->sb.n++] = (uint8_t)(uintptr_t)s; | 1461 | *p++ = (char)(uintptr_t)s; |
1492 | } else { | 1462 | } else { |
1493 | MSize len = s->len+1; | 1463 | MSize len = s->len+1; |
1494 | fs_buf_need(ls, len + 2*5); | 1464 | p = lj_buf_more(&ls->sb, len + 2*5); |
1495 | fs_buf_str(ls, strdata(s), len); | 1465 | p = lj_buf_wmem(p, strdata(s), len); |
1496 | } | 1466 | } |
1497 | startpc = vs->startpc; | 1467 | startpc = vs->startpc; |
1498 | fs_buf_uleb128(ls, startpc-lastpc); | 1468 | p = lj_strfmt_wuleb128(p, startpc-lastpc); |
1499 | fs_buf_uleb128(ls, vs->endpc-startpc); | 1469 | p = lj_strfmt_wuleb128(p, vs->endpc-startpc); |
1470 | setsbufP(&ls->sb, p); | ||
1500 | lastpc = startpc; | 1471 | lastpc = startpc; |
1501 | } | 1472 | } |
1502 | } | 1473 | } |
1503 | fs_buf_need(ls, 1); | 1474 | lj_buf_putb(&ls->sb, '\0'); /* Terminator for varinfo. */ |
1504 | ls->sb.buf[ls->sb.n++] = '\0'; /* Terminator for varinfo. */ | 1475 | return sbuflen(&ls->sb); |
1505 | return ls->sb.n; | ||
1506 | } | 1476 | } |
1507 | 1477 | ||
1508 | /* Fixup variable info for prototype. */ | 1478 | /* Fixup variable info for prototype. */ |
@@ -1510,7 +1480,7 @@ static void fs_fixup_var(LexState *ls, GCproto *pt, uint8_t *p, size_t ofsvar) | |||
1510 | { | 1480 | { |
1511 | setmref(pt->uvinfo, p); | 1481 | setmref(pt->uvinfo, p); |
1512 | setmref(pt->varinfo, (char *)p + ofsvar); | 1482 | setmref(pt->varinfo, (char *)p + ofsvar); |
1513 | memcpy(p, ls->sb.buf, ls->sb.n); /* Copy from temp. string buffer. */ | 1483 | memcpy(p, sbufB(&ls->sb), sbuflen(&ls->sb)); /* Copy from temp. buffer. */ |
1514 | } | 1484 | } |
1515 | #else | 1485 | #else |
1516 | 1486 | ||
@@ -1619,7 +1589,7 @@ static GCproto *fs_finish(LexState *ls, BCLine line) | |||
1619 | L->top--; /* Pop table of constants. */ | 1589 | L->top--; /* Pop table of constants. */ |
1620 | ls->vtop = fs->vbase; /* Reset variable stack. */ | 1590 | ls->vtop = fs->vbase; /* Reset variable stack. */ |
1621 | ls->fs = fs->prev; | 1591 | ls->fs = fs->prev; |
1622 | lua_assert(ls->fs != NULL || ls->token == TK_eof); | 1592 | lua_assert(ls->fs != NULL || ls->tok == TK_eof); |
1623 | return pt; | 1593 | return pt; |
1624 | } | 1594 | } |
1625 | 1595 | ||
@@ -1716,10 +1686,9 @@ static void expr_bracket(LexState *ls, ExpDesc *v) | |||
1716 | static void expr_kvalue(TValue *v, ExpDesc *e) | 1686 | static void expr_kvalue(TValue *v, ExpDesc *e) |
1717 | { | 1687 | { |
1718 | if (e->k <= VKTRUE) { | 1688 | if (e->k <= VKTRUE) { |
1719 | setitype(v, ~(uint32_t)e->k); | 1689 | setpriV(v, ~(uint32_t)e->k); |
1720 | } else if (e->k == VKSTR) { | 1690 | } else if (e->k == VKSTR) { |
1721 | setgcref(v->gcr, obj2gco(e->u.sval)); | 1691 | setgcVraw(v, obj2gco(e->u.sval), LJ_TSTR); |
1722 | setitype(v, LJ_TSTR); | ||
1723 | } else { | 1692 | } else { |
1724 | lua_assert(tvisnumber(expr_numtv(e))); | 1693 | lua_assert(tvisnumber(expr_numtv(e))); |
1725 | *v = *expr_numtv(e); | 1694 | *v = *expr_numtv(e); |
@@ -1741,15 +1710,15 @@ static void expr_table(LexState *ls, ExpDesc *e) | |||
1741 | bcreg_reserve(fs, 1); | 1710 | bcreg_reserve(fs, 1); |
1742 | freg++; | 1711 | freg++; |
1743 | lex_check(ls, '{'); | 1712 | lex_check(ls, '{'); |
1744 | while (ls->token != '}') { | 1713 | while (ls->tok != '}') { |
1745 | ExpDesc key, val; | 1714 | ExpDesc key, val; |
1746 | vcall = 0; | 1715 | vcall = 0; |
1747 | if (ls->token == '[') { | 1716 | if (ls->tok == '[') { |
1748 | expr_bracket(ls, &key); /* Already calls expr_toval. */ | 1717 | expr_bracket(ls, &key); /* Already calls expr_toval. */ |
1749 | if (!expr_isk(&key)) expr_index(fs, e, &key); | 1718 | if (!expr_isk(&key)) expr_index(fs, e, &key); |
1750 | if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++; | 1719 | if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++; |
1751 | lex_check(ls, '='); | 1720 | lex_check(ls, '='); |
1752 | } else if ((ls->token == TK_name || (!LJ_52 && ls->token == TK_goto)) && | 1721 | } else if ((ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) && |
1753 | lj_lex_lookahead(ls) == '=') { | 1722 | lj_lex_lookahead(ls) == '=') { |
1754 | expr_str(ls, &key); | 1723 | expr_str(ls, &key); |
1755 | lex_check(ls, '='); | 1724 | lex_check(ls, '='); |
@@ -1842,11 +1811,11 @@ static BCReg parse_params(LexState *ls, int needself) | |||
1842 | lex_check(ls, '('); | 1811 | lex_check(ls, '('); |
1843 | if (needself) | 1812 | if (needself) |
1844 | var_new_lit(ls, nparams++, "self"); | 1813 | var_new_lit(ls, nparams++, "self"); |
1845 | if (ls->token != ')') { | 1814 | if (ls->tok != ')') { |
1846 | do { | 1815 | do { |
1847 | if (ls->token == TK_name || (!LJ_52 && ls->token == TK_goto)) { | 1816 | if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) { |
1848 | var_new(ls, nparams++, lex_str(ls)); | 1817 | var_new(ls, nparams++, lex_str(ls)); |
1849 | } else if (ls->token == TK_dots) { | 1818 | } else if (ls->tok == TK_dots) { |
1850 | lj_lex_next(ls); | 1819 | lj_lex_next(ls); |
1851 | fs->flags |= PROTO_VARARG; | 1820 | fs->flags |= PROTO_VARARG; |
1852 | break; | 1821 | break; |
@@ -1880,7 +1849,7 @@ static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line) | |||
1880 | fs.bclim = pfs->bclim - pfs->pc; | 1849 | fs.bclim = pfs->bclim - pfs->pc; |
1881 | bcemit_AD(&fs, BC_FUNCF, 0, 0); /* Placeholder. */ | 1850 | bcemit_AD(&fs, BC_FUNCF, 0, 0); /* Placeholder. */ |
1882 | parse_chunk(ls); | 1851 | parse_chunk(ls); |
1883 | if (ls->token != TK_end) lex_match(ls, TK_end, TK_function, line); | 1852 | if (ls->tok != TK_end) lex_match(ls, TK_end, TK_function, line); |
1884 | pt = fs_finish(ls, (ls->lastline = ls->linenumber)); | 1853 | pt = fs_finish(ls, (ls->lastline = ls->linenumber)); |
1885 | pfs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */ | 1854 | pfs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */ |
1886 | pfs->bclim = (BCPos)(ls->sizebcstack - oldbase); | 1855 | pfs->bclim = (BCPos)(ls->sizebcstack - oldbase); |
@@ -1919,13 +1888,13 @@ static void parse_args(LexState *ls, ExpDesc *e) | |||
1919 | BCIns ins; | 1888 | BCIns ins; |
1920 | BCReg base; | 1889 | BCReg base; |
1921 | BCLine line = ls->linenumber; | 1890 | BCLine line = ls->linenumber; |
1922 | if (ls->token == '(') { | 1891 | if (ls->tok == '(') { |
1923 | #if !LJ_52 | 1892 | #if !LJ_52 |
1924 | if (line != ls->lastline) | 1893 | if (line != ls->lastline) |
1925 | err_syntax(ls, LJ_ERR_XAMBIG); | 1894 | err_syntax(ls, LJ_ERR_XAMBIG); |
1926 | #endif | 1895 | #endif |
1927 | lj_lex_next(ls); | 1896 | lj_lex_next(ls); |
1928 | if (ls->token == ')') { /* f(). */ | 1897 | if (ls->tok == ')') { /* f(). */ |
1929 | args.k = VVOID; | 1898 | args.k = VVOID; |
1930 | } else { | 1899 | } else { |
1931 | expr_list(ls, &args); | 1900 | expr_list(ls, &args); |
@@ -1933,11 +1902,11 @@ static void parse_args(LexState *ls, ExpDesc *e) | |||
1933 | setbc_b(bcptr(fs, &args), 0); /* Pass on multiple results. */ | 1902 | setbc_b(bcptr(fs, &args), 0); /* Pass on multiple results. */ |
1934 | } | 1903 | } |
1935 | lex_match(ls, ')', '(', line); | 1904 | lex_match(ls, ')', '(', line); |
1936 | } else if (ls->token == '{') { | 1905 | } else if (ls->tok == '{') { |
1937 | expr_table(ls, &args); | 1906 | expr_table(ls, &args); |
1938 | } else if (ls->token == TK_string) { | 1907 | } else if (ls->tok == TK_string) { |
1939 | expr_init(&args, VKSTR, 0); | 1908 | expr_init(&args, VKSTR, 0); |
1940 | args.u.sval = strV(&ls->tokenval); | 1909 | args.u.sval = strV(&ls->tokval); |
1941 | lj_lex_next(ls); | 1910 | lj_lex_next(ls); |
1942 | } else { | 1911 | } else { |
1943 | err_syntax(ls, LJ_ERR_XFUNARG); | 1912 | err_syntax(ls, LJ_ERR_XFUNARG); |
@@ -1946,11 +1915,11 @@ static void parse_args(LexState *ls, ExpDesc *e) | |||
1946 | lua_assert(e->k == VNONRELOC); | 1915 | lua_assert(e->k == VNONRELOC); |
1947 | base = e->u.s.info; /* Base register for call. */ | 1916 | base = e->u.s.info; /* Base register for call. */ |
1948 | if (args.k == VCALL) { | 1917 | if (args.k == VCALL) { |
1949 | ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1); | 1918 | ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1 - LJ_FR2); |
1950 | } else { | 1919 | } else { |
1951 | if (args.k != VVOID) | 1920 | if (args.k != VVOID) |
1952 | expr_tonextreg(fs, &args); | 1921 | expr_tonextreg(fs, &args); |
1953 | ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base); | 1922 | ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base - LJ_FR2); |
1954 | } | 1923 | } |
1955 | expr_init(e, VCALL, bcemit_INS(fs, ins)); | 1924 | expr_init(e, VCALL, bcemit_INS(fs, ins)); |
1956 | e->u.s.aux = base; | 1925 | e->u.s.aux = base; |
@@ -1963,33 +1932,34 @@ static void expr_primary(LexState *ls, ExpDesc *v) | |||
1963 | { | 1932 | { |
1964 | FuncState *fs = ls->fs; | 1933 | FuncState *fs = ls->fs; |
1965 | /* Parse prefix expression. */ | 1934 | /* Parse prefix expression. */ |
1966 | if (ls->token == '(') { | 1935 | if (ls->tok == '(') { |
1967 | BCLine line = ls->linenumber; | 1936 | BCLine line = ls->linenumber; |
1968 | lj_lex_next(ls); | 1937 | lj_lex_next(ls); |
1969 | expr(ls, v); | 1938 | expr(ls, v); |
1970 | lex_match(ls, ')', '(', line); | 1939 | lex_match(ls, ')', '(', line); |
1971 | expr_discharge(ls->fs, v); | 1940 | expr_discharge(ls->fs, v); |
1972 | } else if (ls->token == TK_name || (!LJ_52 && ls->token == TK_goto)) { | 1941 | } else if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) { |
1973 | var_lookup(ls, v); | 1942 | var_lookup(ls, v); |
1974 | } else { | 1943 | } else { |
1975 | err_syntax(ls, LJ_ERR_XSYMBOL); | 1944 | err_syntax(ls, LJ_ERR_XSYMBOL); |
1976 | } | 1945 | } |
1977 | for (;;) { /* Parse multiple expression suffixes. */ | 1946 | for (;;) { /* Parse multiple expression suffixes. */ |
1978 | if (ls->token == '.') { | 1947 | if (ls->tok == '.') { |
1979 | expr_field(ls, v); | 1948 | expr_field(ls, v); |
1980 | } else if (ls->token == '[') { | 1949 | } else if (ls->tok == '[') { |
1981 | ExpDesc key; | 1950 | ExpDesc key; |
1982 | expr_toanyreg(fs, v); | 1951 | expr_toanyreg(fs, v); |
1983 | expr_bracket(ls, &key); | 1952 | expr_bracket(ls, &key); |
1984 | expr_index(fs, v, &key); | 1953 | expr_index(fs, v, &key); |
1985 | } else if (ls->token == ':') { | 1954 | } else if (ls->tok == ':') { |
1986 | ExpDesc key; | 1955 | ExpDesc key; |
1987 | lj_lex_next(ls); | 1956 | lj_lex_next(ls); |
1988 | expr_str(ls, &key); | 1957 | expr_str(ls, &key); |
1989 | bcemit_method(fs, v, &key); | 1958 | bcemit_method(fs, v, &key); |
1990 | parse_args(ls, v); | 1959 | parse_args(ls, v); |
1991 | } else if (ls->token == '(' || ls->token == TK_string || ls->token == '{') { | 1960 | } else if (ls->tok == '(' || ls->tok == TK_string || ls->tok == '{') { |
1992 | expr_tonextreg(fs, v); | 1961 | expr_tonextreg(fs, v); |
1962 | if (LJ_FR2) bcreg_reserve(fs, 1); | ||
1993 | parse_args(ls, v); | 1963 | parse_args(ls, v); |
1994 | } else { | 1964 | } else { |
1995 | break; | 1965 | break; |
@@ -2000,14 +1970,14 @@ static void expr_primary(LexState *ls, ExpDesc *v) | |||
2000 | /* Parse simple expression. */ | 1970 | /* Parse simple expression. */ |
2001 | static void expr_simple(LexState *ls, ExpDesc *v) | 1971 | static void expr_simple(LexState *ls, ExpDesc *v) |
2002 | { | 1972 | { |
2003 | switch (ls->token) { | 1973 | switch (ls->tok) { |
2004 | case TK_number: | 1974 | case TK_number: |
2005 | expr_init(v, (LJ_HASFFI && tviscdata(&ls->tokenval)) ? VKCDATA : VKNUM, 0); | 1975 | expr_init(v, (LJ_HASFFI && tviscdata(&ls->tokval)) ? VKCDATA : VKNUM, 0); |
2006 | copyTV(ls->L, &v->u.nval, &ls->tokenval); | 1976 | copyTV(ls->L, &v->u.nval, &ls->tokval); |
2007 | break; | 1977 | break; |
2008 | case TK_string: | 1978 | case TK_string: |
2009 | expr_init(v, VKSTR, 0); | 1979 | expr_init(v, VKSTR, 0); |
2010 | v->u.sval = strV(&ls->tokenval); | 1980 | v->u.sval = strV(&ls->tokval); |
2011 | break; | 1981 | break; |
2012 | case TK_nil: | 1982 | case TK_nil: |
2013 | expr_init(v, VKNIL, 0); | 1983 | expr_init(v, VKNIL, 0); |
@@ -2095,11 +2065,11 @@ static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit); | |||
2095 | static void expr_unop(LexState *ls, ExpDesc *v) | 2065 | static void expr_unop(LexState *ls, ExpDesc *v) |
2096 | { | 2066 | { |
2097 | BCOp op; | 2067 | BCOp op; |
2098 | if (ls->token == TK_not) { | 2068 | if (ls->tok == TK_not) { |
2099 | op = BC_NOT; | 2069 | op = BC_NOT; |
2100 | } else if (ls->token == '-') { | 2070 | } else if (ls->tok == '-') { |
2101 | op = BC_UNM; | 2071 | op = BC_UNM; |
2102 | } else if (ls->token == '#') { | 2072 | } else if (ls->tok == '#') { |
2103 | op = BC_LEN; | 2073 | op = BC_LEN; |
2104 | } else { | 2074 | } else { |
2105 | expr_simple(ls, v); | 2075 | expr_simple(ls, v); |
@@ -2116,7 +2086,7 @@ static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit) | |||
2116 | BinOpr op; | 2086 | BinOpr op; |
2117 | synlevel_begin(ls); | 2087 | synlevel_begin(ls); |
2118 | expr_unop(ls, v); | 2088 | expr_unop(ls, v); |
2119 | op = token2binop(ls->token); | 2089 | op = token2binop(ls->tok); |
2120 | while (op != OPR_NOBINOPR && priority[op].left > limit) { | 2090 | while (op != OPR_NOBINOPR && priority[op].left > limit) { |
2121 | ExpDesc v2; | 2091 | ExpDesc v2; |
2122 | BinOpr nextop; | 2092 | BinOpr nextop; |
@@ -2305,9 +2275,9 @@ static void parse_func(LexState *ls, BCLine line) | |||
2305 | lj_lex_next(ls); /* Skip 'function'. */ | 2275 | lj_lex_next(ls); /* Skip 'function'. */ |
2306 | /* Parse function name. */ | 2276 | /* Parse function name. */ |
2307 | var_lookup(ls, &v); | 2277 | var_lookup(ls, &v); |
2308 | while (ls->token == '.') /* Multiple dot-separated fields. */ | 2278 | while (ls->tok == '.') /* Multiple dot-separated fields. */ |
2309 | expr_field(ls, &v); | 2279 | expr_field(ls, &v); |
2310 | if (ls->token == ':') { /* Optional colon to signify method call. */ | 2280 | if (ls->tok == ':') { /* Optional colon to signify method call. */ |
2311 | needself = 1; | 2281 | needself = 1; |
2312 | expr_field(ls, &v); | 2282 | expr_field(ls, &v); |
2313 | } | 2283 | } |
@@ -2320,9 +2290,9 @@ static void parse_func(LexState *ls, BCLine line) | |||
2320 | /* -- Control transfer statements ----------------------------------------- */ | 2290 | /* -- Control transfer statements ----------------------------------------- */ |
2321 | 2291 | ||
2322 | /* Check for end of block. */ | 2292 | /* Check for end of block. */ |
2323 | static int endofblock(LexToken token) | 2293 | static int parse_isend(LexToken tok) |
2324 | { | 2294 | { |
2325 | switch (token) { | 2295 | switch (tok) { |
2326 | case TK_else: case TK_elseif: case TK_end: case TK_until: case TK_eof: | 2296 | case TK_else: case TK_elseif: case TK_end: case TK_until: case TK_eof: |
2327 | return 1; | 2297 | return 1; |
2328 | default: | 2298 | default: |
@@ -2337,7 +2307,7 @@ static void parse_return(LexState *ls) | |||
2337 | FuncState *fs = ls->fs; | 2307 | FuncState *fs = ls->fs; |
2338 | lj_lex_next(ls); /* Skip 'return'. */ | 2308 | lj_lex_next(ls); /* Skip 'return'. */ |
2339 | fs->flags |= PROTO_HAS_RETURN; | 2309 | fs->flags |= PROTO_HAS_RETURN; |
2340 | if (endofblock(ls->token) || ls->token == ';') { /* Bare return. */ | 2310 | if (parse_isend(ls->tok) || ls->tok == ';') { /* Bare return. */ |
2341 | ins = BCINS_AD(BC_RET0, 0, 1); | 2311 | ins = BCINS_AD(BC_RET0, 0, 1); |
2342 | } else { /* Return with one or more values. */ | 2312 | } else { /* Return with one or more values. */ |
2343 | ExpDesc e; /* Receives the _last_ expression in the list. */ | 2313 | ExpDesc e; /* Receives the _last_ expression in the list. */ |
@@ -2403,18 +2373,18 @@ static void parse_label(LexState *ls) | |||
2403 | lex_check(ls, TK_label); | 2373 | lex_check(ls, TK_label); |
2404 | /* Recursively parse trailing statements: labels and ';' (Lua 5.2 only). */ | 2374 | /* Recursively parse trailing statements: labels and ';' (Lua 5.2 only). */ |
2405 | for (;;) { | 2375 | for (;;) { |
2406 | if (ls->token == TK_label) { | 2376 | if (ls->tok == TK_label) { |
2407 | synlevel_begin(ls); | 2377 | synlevel_begin(ls); |
2408 | parse_label(ls); | 2378 | parse_label(ls); |
2409 | synlevel_end(ls); | 2379 | synlevel_end(ls); |
2410 | } else if (LJ_52 && ls->token == ';') { | 2380 | } else if (LJ_52 && ls->tok == ';') { |
2411 | lj_lex_next(ls); | 2381 | lj_lex_next(ls); |
2412 | } else { | 2382 | } else { |
2413 | break; | 2383 | break; |
2414 | } | 2384 | } |
2415 | } | 2385 | } |
2416 | /* Trailing label is considered to be outside of scope. */ | 2386 | /* Trailing label is considered to be outside of scope. */ |
2417 | if (endofblock(ls->token) && ls->token != TK_until) | 2387 | if (parse_isend(ls->tok) && ls->tok != TK_until) |
2418 | ls->vstack[idx].slot = fs->bl->nactvar; | 2388 | ls->vstack[idx].slot = fs->bl->nactvar; |
2419 | gola_resolve(ls, fs->bl, idx); | 2389 | gola_resolve(ls, fs->bl, idx); |
2420 | } | 2390 | } |
@@ -2570,7 +2540,8 @@ static void parse_for_iter(LexState *ls, GCstr *indexname) | |||
2570 | lex_check(ls, TK_in); | 2540 | lex_check(ls, TK_in); |
2571 | line = ls->linenumber; | 2541 | line = ls->linenumber; |
2572 | assign_adjust(ls, 3, expr_list(ls, &e), &e); | 2542 | assign_adjust(ls, 3, expr_list(ls, &e), &e); |
2573 | bcreg_bump(fs, 3); /* The iterator needs another 3 slots (func + 2 args). */ | 2543 | /* The iterator needs another 3 [4] slots (func [pc] | state ctl). */ |
2544 | bcreg_bump(fs, 3+LJ_FR2); | ||
2574 | isnext = (nvars <= 5 && predict_next(ls, fs, exprpc)); | 2545 | isnext = (nvars <= 5 && predict_next(ls, fs, exprpc)); |
2575 | var_add(ls, 3); /* Hidden control variables. */ | 2546 | var_add(ls, 3); /* Hidden control variables. */ |
2576 | lex_check(ls, TK_do); | 2547 | lex_check(ls, TK_do); |
@@ -2598,9 +2569,9 @@ static void parse_for(LexState *ls, BCLine line) | |||
2598 | fscope_begin(fs, &bl, FSCOPE_LOOP); | 2569 | fscope_begin(fs, &bl, FSCOPE_LOOP); |
2599 | lj_lex_next(ls); /* Skip 'for'. */ | 2570 | lj_lex_next(ls); /* Skip 'for'. */ |
2600 | varname = lex_str(ls); /* Get first variable name. */ | 2571 | varname = lex_str(ls); /* Get first variable name. */ |
2601 | if (ls->token == '=') | 2572 | if (ls->tok == '=') |
2602 | parse_for_num(ls, varname, line); | 2573 | parse_for_num(ls, varname, line); |
2603 | else if (ls->token == ',' || ls->token == TK_in) | 2574 | else if (ls->tok == ',' || ls->tok == TK_in) |
2604 | parse_for_iter(ls, varname); | 2575 | parse_for_iter(ls, varname); |
2605 | else | 2576 | else |
2606 | err_syntax(ls, LJ_ERR_XFOR); | 2577 | err_syntax(ls, LJ_ERR_XFOR); |
@@ -2626,12 +2597,12 @@ static void parse_if(LexState *ls, BCLine line) | |||
2626 | BCPos flist; | 2597 | BCPos flist; |
2627 | BCPos escapelist = NO_JMP; | 2598 | BCPos escapelist = NO_JMP; |
2628 | flist = parse_then(ls); | 2599 | flist = parse_then(ls); |
2629 | while (ls->token == TK_elseif) { /* Parse multiple 'elseif' blocks. */ | 2600 | while (ls->tok == TK_elseif) { /* Parse multiple 'elseif' blocks. */ |
2630 | jmp_append(fs, &escapelist, bcemit_jmp(fs)); | 2601 | jmp_append(fs, &escapelist, bcemit_jmp(fs)); |
2631 | jmp_tohere(fs, flist); | 2602 | jmp_tohere(fs, flist); |
2632 | flist = parse_then(ls); | 2603 | flist = parse_then(ls); |
2633 | } | 2604 | } |
2634 | if (ls->token == TK_else) { /* Parse optional 'else' block. */ | 2605 | if (ls->tok == TK_else) { /* Parse optional 'else' block. */ |
2635 | jmp_append(fs, &escapelist, bcemit_jmp(fs)); | 2606 | jmp_append(fs, &escapelist, bcemit_jmp(fs)); |
2636 | jmp_tohere(fs, flist); | 2607 | jmp_tohere(fs, flist); |
2637 | lj_lex_next(ls); /* Skip 'else'. */ | 2608 | lj_lex_next(ls); /* Skip 'else'. */ |
@@ -2649,7 +2620,7 @@ static void parse_if(LexState *ls, BCLine line) | |||
2649 | static int parse_stmt(LexState *ls) | 2620 | static int parse_stmt(LexState *ls) |
2650 | { | 2621 | { |
2651 | BCLine line = ls->linenumber; | 2622 | BCLine line = ls->linenumber; |
2652 | switch (ls->token) { | 2623 | switch (ls->tok) { |
2653 | case TK_if: | 2624 | case TK_if: |
2654 | parse_if(ls, line); | 2625 | parse_if(ls, line); |
2655 | break; | 2626 | break; |
@@ -2707,7 +2678,7 @@ static void parse_chunk(LexState *ls) | |||
2707 | { | 2678 | { |
2708 | int islast = 0; | 2679 | int islast = 0; |
2709 | synlevel_begin(ls); | 2680 | synlevel_begin(ls); |
2710 | while (!islast && !endofblock(ls->token)) { | 2681 | while (!islast && !parse_isend(ls->tok)) { |
2711 | islast = parse_stmt(ls); | 2682 | islast = parse_stmt(ls); |
2712 | lex_opt(ls, ';'); | 2683 | lex_opt(ls, ';'); |
2713 | lua_assert(ls->fs->framesize >= ls->fs->freereg && | 2684 | lua_assert(ls->fs->framesize >= ls->fs->freereg && |
@@ -2742,7 +2713,7 @@ GCproto *lj_parse(LexState *ls) | |||
2742 | bcemit_AD(&fs, BC_FUNCV, 0, 0); /* Placeholder. */ | 2713 | bcemit_AD(&fs, BC_FUNCV, 0, 0); /* Placeholder. */ |
2743 | lj_lex_next(ls); /* Read-ahead first token. */ | 2714 | lj_lex_next(ls); /* Read-ahead first token. */ |
2744 | parse_chunk(ls); | 2715 | parse_chunk(ls); |
2745 | if (ls->token != TK_eof) | 2716 | if (ls->tok != TK_eof) |
2746 | err_token(ls, TK_eof); | 2717 | err_token(ls, TK_eof); |
2747 | pt = fs_finish(ls, ls->linenumber); | 2718 | pt = fs_finish(ls, ls->linenumber); |
2748 | L->top--; /* Drop chunkname. */ | 2719 | L->top--; /* Drop chunkname. */ |