diff options
Diffstat (limited to 'src/lj_parse.c')
-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 74dd5706..68f3789e 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 | } |
@@ -1433,78 +1435,46 @@ static void fs_fixup_line(FuncState *fs, GCproto *pt, | |||
1433 | } | 1435 | } |
1434 | } | 1436 | } |
1435 | 1437 | ||
1436 | /* Resize buffer if needed. */ | ||
1437 | static LJ_NOINLINE void fs_buf_resize(LexState *ls, MSize len) | ||
1438 | { | ||
1439 | MSize sz = ls->sb.sz * 2; | ||
1440 | while (ls->sb.n + len > sz) sz = sz * 2; | ||
1441 | lj_str_resizebuf(ls->L, &ls->sb, sz); | ||
1442 | } | ||
1443 | |||
1444 | static LJ_AINLINE void fs_buf_need(LexState *ls, MSize len) | ||
1445 | { | ||
1446 | if (LJ_UNLIKELY(ls->sb.n + len > ls->sb.sz)) | ||
1447 | fs_buf_resize(ls, len); | ||
1448 | } | ||
1449 | |||
1450 | /* Add string to buffer. */ | ||
1451 | static void fs_buf_str(LexState *ls, const char *str, MSize len) | ||
1452 | { | ||
1453 | char *p = ls->sb.buf + ls->sb.n; | ||
1454 | MSize i; | ||
1455 | ls->sb.n += len; | ||
1456 | for (i = 0; i < len; i++) p[i] = str[i]; | ||
1457 | } | ||
1458 | |||
1459 | /* Add ULEB128 value to buffer. */ | ||
1460 | static void fs_buf_uleb128(LexState *ls, uint32_t v) | ||
1461 | { | ||
1462 | MSize n = ls->sb.n; | ||
1463 | uint8_t *p = (uint8_t *)ls->sb.buf; | ||
1464 | for (; v >= 0x80; v >>= 7) | ||
1465 | p[n++] = (uint8_t)((v & 0x7f) | 0x80); | ||
1466 | p[n++] = (uint8_t)v; | ||
1467 | ls->sb.n = n; | ||
1468 | } | ||
1469 | |||
1470 | /* Prepare variable info for prototype. */ | 1438 | /* Prepare variable info for prototype. */ |
1471 | static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar) | 1439 | static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar) |
1472 | { | 1440 | { |
1473 | VarInfo *vs =ls->vstack, *ve; | 1441 | VarInfo *vs =ls->vstack, *ve; |
1474 | MSize i, n; | 1442 | MSize i, n; |
1475 | BCPos lastpc; | 1443 | BCPos lastpc; |
1476 | lj_str_resetbuf(&ls->sb); /* Copy to temp. string buffer. */ | 1444 | lj_buf_reset(&ls->sb); /* Copy to temp. string buffer. */ |
1477 | /* Store upvalue names. */ | 1445 | /* Store upvalue names. */ |
1478 | for (i = 0, n = fs->nuv; i < n; i++) { | 1446 | for (i = 0, n = fs->nuv; i < n; i++) { |
1479 | GCstr *s = strref(vs[fs->uvmap[i]].name); | 1447 | GCstr *s = strref(vs[fs->uvmap[i]].name); |
1480 | MSize len = s->len+1; | 1448 | MSize len = s->len+1; |
1481 | fs_buf_need(ls, len); | 1449 | char *p = lj_buf_more(&ls->sb, len); |
1482 | fs_buf_str(ls, strdata(s), len); | 1450 | p = lj_buf_wmem(p, strdata(s), len); |
1451 | setsbufP(&ls->sb, p); | ||
1483 | } | 1452 | } |
1484 | *ofsvar = ls->sb.n; | 1453 | *ofsvar = sbuflen(&ls->sb); |
1485 | lastpc = 0; | 1454 | lastpc = 0; |
1486 | /* Store local variable names and compressed ranges. */ | 1455 | /* Store local variable names and compressed ranges. */ |
1487 | for (ve = vs + ls->vtop, vs += fs->vbase; vs < ve; vs++) { | 1456 | for (ve = vs + ls->vtop, vs += fs->vbase; vs < ve; vs++) { |
1488 | if (!gola_isgotolabel(vs)) { | 1457 | if (!gola_isgotolabel(vs)) { |
1489 | GCstr *s = strref(vs->name); | 1458 | GCstr *s = strref(vs->name); |
1490 | BCPos startpc; | 1459 | BCPos startpc; |
1460 | char *p; | ||
1491 | if ((uintptr_t)s < VARNAME__MAX) { | 1461 | if ((uintptr_t)s < VARNAME__MAX) { |
1492 | fs_buf_need(ls, 1 + 2*5); | 1462 | p = lj_buf_more(&ls->sb, 1 + 2*5); |
1493 | ls->sb.buf[ls->sb.n++] = (uint8_t)(uintptr_t)s; | 1463 | *p++ = (char)(uintptr_t)s; |
1494 | } else { | 1464 | } else { |
1495 | MSize len = s->len+1; | 1465 | MSize len = s->len+1; |
1496 | fs_buf_need(ls, len + 2*5); | 1466 | p = lj_buf_more(&ls->sb, len + 2*5); |
1497 | fs_buf_str(ls, strdata(s), len); | 1467 | p = lj_buf_wmem(p, strdata(s), len); |
1498 | } | 1468 | } |
1499 | startpc = vs->startpc; | 1469 | startpc = vs->startpc; |
1500 | fs_buf_uleb128(ls, startpc-lastpc); | 1470 | p = lj_strfmt_wuleb128(p, startpc-lastpc); |
1501 | fs_buf_uleb128(ls, vs->endpc-startpc); | 1471 | p = lj_strfmt_wuleb128(p, vs->endpc-startpc); |
1472 | setsbufP(&ls->sb, p); | ||
1502 | lastpc = startpc; | 1473 | lastpc = startpc; |
1503 | } | 1474 | } |
1504 | } | 1475 | } |
1505 | fs_buf_need(ls, 1); | 1476 | lj_buf_putb(&ls->sb, '\0'); /* Terminator for varinfo. */ |
1506 | ls->sb.buf[ls->sb.n++] = '\0'; /* Terminator for varinfo. */ | 1477 | return sbuflen(&ls->sb); |
1507 | return ls->sb.n; | ||
1508 | } | 1478 | } |
1509 | 1479 | ||
1510 | /* Fixup variable info for prototype. */ | 1480 | /* Fixup variable info for prototype. */ |
@@ -1512,7 +1482,7 @@ static void fs_fixup_var(LexState *ls, GCproto *pt, uint8_t *p, size_t ofsvar) | |||
1512 | { | 1482 | { |
1513 | setmref(pt->uvinfo, p); | 1483 | setmref(pt->uvinfo, p); |
1514 | setmref(pt->varinfo, (char *)p + ofsvar); | 1484 | setmref(pt->varinfo, (char *)p + ofsvar); |
1515 | memcpy(p, ls->sb.buf, ls->sb.n); /* Copy from temp. string buffer. */ | 1485 | memcpy(p, sbufB(&ls->sb), sbuflen(&ls->sb)); /* Copy from temp. buffer. */ |
1516 | } | 1486 | } |
1517 | #else | 1487 | #else |
1518 | 1488 | ||
@@ -1621,7 +1591,7 @@ static GCproto *fs_finish(LexState *ls, BCLine line) | |||
1621 | L->top--; /* Pop table of constants. */ | 1591 | L->top--; /* Pop table of constants. */ |
1622 | ls->vtop = fs->vbase; /* Reset variable stack. */ | 1592 | ls->vtop = fs->vbase; /* Reset variable stack. */ |
1623 | ls->fs = fs->prev; | 1593 | ls->fs = fs->prev; |
1624 | lua_assert(ls->fs != NULL || ls->token == TK_eof); | 1594 | lua_assert(ls->fs != NULL || ls->tok == TK_eof); |
1625 | return pt; | 1595 | return pt; |
1626 | } | 1596 | } |
1627 | 1597 | ||
@@ -1718,10 +1688,9 @@ static void expr_bracket(LexState *ls, ExpDesc *v) | |||
1718 | static void expr_kvalue(TValue *v, ExpDesc *e) | 1688 | static void expr_kvalue(TValue *v, ExpDesc *e) |
1719 | { | 1689 | { |
1720 | if (e->k <= VKTRUE) { | 1690 | if (e->k <= VKTRUE) { |
1721 | setitype(v, ~(uint32_t)e->k); | 1691 | setpriV(v, ~(uint32_t)e->k); |
1722 | } else if (e->k == VKSTR) { | 1692 | } else if (e->k == VKSTR) { |
1723 | setgcref(v->gcr, obj2gco(e->u.sval)); | 1693 | setgcVraw(v, obj2gco(e->u.sval), LJ_TSTR); |
1724 | setitype(v, LJ_TSTR); | ||
1725 | } else { | 1694 | } else { |
1726 | lua_assert(tvisnumber(expr_numtv(e))); | 1695 | lua_assert(tvisnumber(expr_numtv(e))); |
1727 | *v = *expr_numtv(e); | 1696 | *v = *expr_numtv(e); |
@@ -1743,15 +1712,15 @@ static void expr_table(LexState *ls, ExpDesc *e) | |||
1743 | bcreg_reserve(fs, 1); | 1712 | bcreg_reserve(fs, 1); |
1744 | freg++; | 1713 | freg++; |
1745 | lex_check(ls, '{'); | 1714 | lex_check(ls, '{'); |
1746 | while (ls->token != '}') { | 1715 | while (ls->tok != '}') { |
1747 | ExpDesc key, val; | 1716 | ExpDesc key, val; |
1748 | vcall = 0; | 1717 | vcall = 0; |
1749 | if (ls->token == '[') { | 1718 | if (ls->tok == '[') { |
1750 | expr_bracket(ls, &key); /* Already calls expr_toval. */ | 1719 | expr_bracket(ls, &key); /* Already calls expr_toval. */ |
1751 | if (!expr_isk(&key)) expr_index(fs, e, &key); | 1720 | if (!expr_isk(&key)) expr_index(fs, e, &key); |
1752 | if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++; | 1721 | if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++; |
1753 | lex_check(ls, '='); | 1722 | lex_check(ls, '='); |
1754 | } else if ((ls->token == TK_name || (!LJ_52 && ls->token == TK_goto)) && | 1723 | } else if ((ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) && |
1755 | lj_lex_lookahead(ls) == '=') { | 1724 | lj_lex_lookahead(ls) == '=') { |
1756 | expr_str(ls, &key); | 1725 | expr_str(ls, &key); |
1757 | lex_check(ls, '='); | 1726 | lex_check(ls, '='); |
@@ -1844,11 +1813,11 @@ static BCReg parse_params(LexState *ls, int needself) | |||
1844 | lex_check(ls, '('); | 1813 | lex_check(ls, '('); |
1845 | if (needself) | 1814 | if (needself) |
1846 | var_new_lit(ls, nparams++, "self"); | 1815 | var_new_lit(ls, nparams++, "self"); |
1847 | if (ls->token != ')') { | 1816 | if (ls->tok != ')') { |
1848 | do { | 1817 | do { |
1849 | if (ls->token == TK_name || (!LJ_52 && ls->token == TK_goto)) { | 1818 | if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) { |
1850 | var_new(ls, nparams++, lex_str(ls)); | 1819 | var_new(ls, nparams++, lex_str(ls)); |
1851 | } else if (ls->token == TK_dots) { | 1820 | } else if (ls->tok == TK_dots) { |
1852 | lj_lex_next(ls); | 1821 | lj_lex_next(ls); |
1853 | fs->flags |= PROTO_VARARG; | 1822 | fs->flags |= PROTO_VARARG; |
1854 | break; | 1823 | break; |
@@ -1882,7 +1851,7 @@ static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line) | |||
1882 | fs.bclim = pfs->bclim - pfs->pc; | 1851 | fs.bclim = pfs->bclim - pfs->pc; |
1883 | bcemit_AD(&fs, BC_FUNCF, 0, 0); /* Placeholder. */ | 1852 | bcemit_AD(&fs, BC_FUNCF, 0, 0); /* Placeholder. */ |
1884 | parse_chunk(ls); | 1853 | parse_chunk(ls); |
1885 | if (ls->token != TK_end) lex_match(ls, TK_end, TK_function, line); | 1854 | if (ls->tok != TK_end) lex_match(ls, TK_end, TK_function, line); |
1886 | pt = fs_finish(ls, (ls->lastline = ls->linenumber)); | 1855 | pt = fs_finish(ls, (ls->lastline = ls->linenumber)); |
1887 | pfs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */ | 1856 | pfs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */ |
1888 | pfs->bclim = (BCPos)(ls->sizebcstack - oldbase); | 1857 | pfs->bclim = (BCPos)(ls->sizebcstack - oldbase); |
@@ -1921,13 +1890,13 @@ static void parse_args(LexState *ls, ExpDesc *e) | |||
1921 | BCIns ins; | 1890 | BCIns ins; |
1922 | BCReg base; | 1891 | BCReg base; |
1923 | BCLine line = ls->linenumber; | 1892 | BCLine line = ls->linenumber; |
1924 | if (ls->token == '(') { | 1893 | if (ls->tok == '(') { |
1925 | #if !LJ_52 | 1894 | #if !LJ_52 |
1926 | if (line != ls->lastline) | 1895 | if (line != ls->lastline) |
1927 | err_syntax(ls, LJ_ERR_XAMBIG); | 1896 | err_syntax(ls, LJ_ERR_XAMBIG); |
1928 | #endif | 1897 | #endif |
1929 | lj_lex_next(ls); | 1898 | lj_lex_next(ls); |
1930 | if (ls->token == ')') { /* f(). */ | 1899 | if (ls->tok == ')') { /* f(). */ |
1931 | args.k = VVOID; | 1900 | args.k = VVOID; |
1932 | } else { | 1901 | } else { |
1933 | expr_list(ls, &args); | 1902 | expr_list(ls, &args); |
@@ -1935,11 +1904,11 @@ static void parse_args(LexState *ls, ExpDesc *e) | |||
1935 | setbc_b(bcptr(fs, &args), 0); /* Pass on multiple results. */ | 1904 | setbc_b(bcptr(fs, &args), 0); /* Pass on multiple results. */ |
1936 | } | 1905 | } |
1937 | lex_match(ls, ')', '(', line); | 1906 | lex_match(ls, ')', '(', line); |
1938 | } else if (ls->token == '{') { | 1907 | } else if (ls->tok == '{') { |
1939 | expr_table(ls, &args); | 1908 | expr_table(ls, &args); |
1940 | } else if (ls->token == TK_string) { | 1909 | } else if (ls->tok == TK_string) { |
1941 | expr_init(&args, VKSTR, 0); | 1910 | expr_init(&args, VKSTR, 0); |
1942 | args.u.sval = strV(&ls->tokenval); | 1911 | args.u.sval = strV(&ls->tokval); |
1943 | lj_lex_next(ls); | 1912 | lj_lex_next(ls); |
1944 | } else { | 1913 | } else { |
1945 | err_syntax(ls, LJ_ERR_XFUNARG); | 1914 | err_syntax(ls, LJ_ERR_XFUNARG); |
@@ -1948,11 +1917,11 @@ static void parse_args(LexState *ls, ExpDesc *e) | |||
1948 | lua_assert(e->k == VNONRELOC); | 1917 | lua_assert(e->k == VNONRELOC); |
1949 | base = e->u.s.info; /* Base register for call. */ | 1918 | base = e->u.s.info; /* Base register for call. */ |
1950 | if (args.k == VCALL) { | 1919 | if (args.k == VCALL) { |
1951 | ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1); | 1920 | ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1 - LJ_FR2); |
1952 | } else { | 1921 | } else { |
1953 | if (args.k != VVOID) | 1922 | if (args.k != VVOID) |
1954 | expr_tonextreg(fs, &args); | 1923 | expr_tonextreg(fs, &args); |
1955 | ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base); | 1924 | ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base - LJ_FR2); |
1956 | } | 1925 | } |
1957 | expr_init(e, VCALL, bcemit_INS(fs, ins)); | 1926 | expr_init(e, VCALL, bcemit_INS(fs, ins)); |
1958 | e->u.s.aux = base; | 1927 | e->u.s.aux = base; |
@@ -1965,33 +1934,34 @@ static void expr_primary(LexState *ls, ExpDesc *v) | |||
1965 | { | 1934 | { |
1966 | FuncState *fs = ls->fs; | 1935 | FuncState *fs = ls->fs; |
1967 | /* Parse prefix expression. */ | 1936 | /* Parse prefix expression. */ |
1968 | if (ls->token == '(') { | 1937 | if (ls->tok == '(') { |
1969 | BCLine line = ls->linenumber; | 1938 | BCLine line = ls->linenumber; |
1970 | lj_lex_next(ls); | 1939 | lj_lex_next(ls); |
1971 | expr(ls, v); | 1940 | expr(ls, v); |
1972 | lex_match(ls, ')', '(', line); | 1941 | lex_match(ls, ')', '(', line); |
1973 | expr_discharge(ls->fs, v); | 1942 | expr_discharge(ls->fs, v); |
1974 | } else if (ls->token == TK_name || (!LJ_52 && ls->token == TK_goto)) { | 1943 | } else if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) { |
1975 | var_lookup(ls, v); | 1944 | var_lookup(ls, v); |
1976 | } else { | 1945 | } else { |
1977 | err_syntax(ls, LJ_ERR_XSYMBOL); | 1946 | err_syntax(ls, LJ_ERR_XSYMBOL); |
1978 | } | 1947 | } |
1979 | for (;;) { /* Parse multiple expression suffixes. */ | 1948 | for (;;) { /* Parse multiple expression suffixes. */ |
1980 | if (ls->token == '.') { | 1949 | if (ls->tok == '.') { |
1981 | expr_field(ls, v); | 1950 | expr_field(ls, v); |
1982 | } else if (ls->token == '[') { | 1951 | } else if (ls->tok == '[') { |
1983 | ExpDesc key; | 1952 | ExpDesc key; |
1984 | expr_toanyreg(fs, v); | 1953 | expr_toanyreg(fs, v); |
1985 | expr_bracket(ls, &key); | 1954 | expr_bracket(ls, &key); |
1986 | expr_index(fs, v, &key); | 1955 | expr_index(fs, v, &key); |
1987 | } else if (ls->token == ':') { | 1956 | } else if (ls->tok == ':') { |
1988 | ExpDesc key; | 1957 | ExpDesc key; |
1989 | lj_lex_next(ls); | 1958 | lj_lex_next(ls); |
1990 | expr_str(ls, &key); | 1959 | expr_str(ls, &key); |
1991 | bcemit_method(fs, v, &key); | 1960 | bcemit_method(fs, v, &key); |
1992 | parse_args(ls, v); | 1961 | parse_args(ls, v); |
1993 | } else if (ls->token == '(' || ls->token == TK_string || ls->token == '{') { | 1962 | } else if (ls->tok == '(' || ls->tok == TK_string || ls->tok == '{') { |
1994 | expr_tonextreg(fs, v); | 1963 | expr_tonextreg(fs, v); |
1964 | if (LJ_FR2) bcreg_reserve(fs, 1); | ||
1995 | parse_args(ls, v); | 1965 | parse_args(ls, v); |
1996 | } else { | 1966 | } else { |
1997 | break; | 1967 | break; |
@@ -2002,14 +1972,14 @@ static void expr_primary(LexState *ls, ExpDesc *v) | |||
2002 | /* Parse simple expression. */ | 1972 | /* Parse simple expression. */ |
2003 | static void expr_simple(LexState *ls, ExpDesc *v) | 1973 | static void expr_simple(LexState *ls, ExpDesc *v) |
2004 | { | 1974 | { |
2005 | switch (ls->token) { | 1975 | switch (ls->tok) { |
2006 | case TK_number: | 1976 | case TK_number: |
2007 | expr_init(v, (LJ_HASFFI && tviscdata(&ls->tokenval)) ? VKCDATA : VKNUM, 0); | 1977 | expr_init(v, (LJ_HASFFI && tviscdata(&ls->tokval)) ? VKCDATA : VKNUM, 0); |
2008 | copyTV(ls->L, &v->u.nval, &ls->tokenval); | 1978 | copyTV(ls->L, &v->u.nval, &ls->tokval); |
2009 | break; | 1979 | break; |
2010 | case TK_string: | 1980 | case TK_string: |
2011 | expr_init(v, VKSTR, 0); | 1981 | expr_init(v, VKSTR, 0); |
2012 | v->u.sval = strV(&ls->tokenval); | 1982 | v->u.sval = strV(&ls->tokval); |
2013 | break; | 1983 | break; |
2014 | case TK_nil: | 1984 | case TK_nil: |
2015 | expr_init(v, VKNIL, 0); | 1985 | expr_init(v, VKNIL, 0); |
@@ -2097,11 +2067,11 @@ static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit); | |||
2097 | static void expr_unop(LexState *ls, ExpDesc *v) | 2067 | static void expr_unop(LexState *ls, ExpDesc *v) |
2098 | { | 2068 | { |
2099 | BCOp op; | 2069 | BCOp op; |
2100 | if (ls->token == TK_not) { | 2070 | if (ls->tok == TK_not) { |
2101 | op = BC_NOT; | 2071 | op = BC_NOT; |
2102 | } else if (ls->token == '-') { | 2072 | } else if (ls->tok == '-') { |
2103 | op = BC_UNM; | 2073 | op = BC_UNM; |
2104 | } else if (ls->token == '#') { | 2074 | } else if (ls->tok == '#') { |
2105 | op = BC_LEN; | 2075 | op = BC_LEN; |
2106 | } else { | 2076 | } else { |
2107 | expr_simple(ls, v); | 2077 | expr_simple(ls, v); |
@@ -2118,7 +2088,7 @@ static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit) | |||
2118 | BinOpr op; | 2088 | BinOpr op; |
2119 | synlevel_begin(ls); | 2089 | synlevel_begin(ls); |
2120 | expr_unop(ls, v); | 2090 | expr_unop(ls, v); |
2121 | op = token2binop(ls->token); | 2091 | op = token2binop(ls->tok); |
2122 | while (op != OPR_NOBINOPR && priority[op].left > limit) { | 2092 | while (op != OPR_NOBINOPR && priority[op].left > limit) { |
2123 | ExpDesc v2; | 2093 | ExpDesc v2; |
2124 | BinOpr nextop; | 2094 | BinOpr nextop; |
@@ -2307,9 +2277,9 @@ static void parse_func(LexState *ls, BCLine line) | |||
2307 | lj_lex_next(ls); /* Skip 'function'. */ | 2277 | lj_lex_next(ls); /* Skip 'function'. */ |
2308 | /* Parse function name. */ | 2278 | /* Parse function name. */ |
2309 | var_lookup(ls, &v); | 2279 | var_lookup(ls, &v); |
2310 | while (ls->token == '.') /* Multiple dot-separated fields. */ | 2280 | while (ls->tok == '.') /* Multiple dot-separated fields. */ |
2311 | expr_field(ls, &v); | 2281 | expr_field(ls, &v); |
2312 | if (ls->token == ':') { /* Optional colon to signify method call. */ | 2282 | if (ls->tok == ':') { /* Optional colon to signify method call. */ |
2313 | needself = 1; | 2283 | needself = 1; |
2314 | expr_field(ls, &v); | 2284 | expr_field(ls, &v); |
2315 | } | 2285 | } |
@@ -2322,9 +2292,9 @@ static void parse_func(LexState *ls, BCLine line) | |||
2322 | /* -- Control transfer statements ----------------------------------------- */ | 2292 | /* -- Control transfer statements ----------------------------------------- */ |
2323 | 2293 | ||
2324 | /* Check for end of block. */ | 2294 | /* Check for end of block. */ |
2325 | static int endofblock(LexToken token) | 2295 | static int parse_isend(LexToken tok) |
2326 | { | 2296 | { |
2327 | switch (token) { | 2297 | switch (tok) { |
2328 | case TK_else: case TK_elseif: case TK_end: case TK_until: case TK_eof: | 2298 | case TK_else: case TK_elseif: case TK_end: case TK_until: case TK_eof: |
2329 | return 1; | 2299 | return 1; |
2330 | default: | 2300 | default: |
@@ -2339,7 +2309,7 @@ static void parse_return(LexState *ls) | |||
2339 | FuncState *fs = ls->fs; | 2309 | FuncState *fs = ls->fs; |
2340 | lj_lex_next(ls); /* Skip 'return'. */ | 2310 | lj_lex_next(ls); /* Skip 'return'. */ |
2341 | fs->flags |= PROTO_HAS_RETURN; | 2311 | fs->flags |= PROTO_HAS_RETURN; |
2342 | if (endofblock(ls->token) || ls->token == ';') { /* Bare return. */ | 2312 | if (parse_isend(ls->tok) || ls->tok == ';') { /* Bare return. */ |
2343 | ins = BCINS_AD(BC_RET0, 0, 1); | 2313 | ins = BCINS_AD(BC_RET0, 0, 1); |
2344 | } else { /* Return with one or more values. */ | 2314 | } else { /* Return with one or more values. */ |
2345 | ExpDesc e; /* Receives the _last_ expression in the list. */ | 2315 | ExpDesc e; /* Receives the _last_ expression in the list. */ |
@@ -2405,18 +2375,18 @@ static void parse_label(LexState *ls) | |||
2405 | lex_check(ls, TK_label); | 2375 | lex_check(ls, TK_label); |
2406 | /* Recursively parse trailing statements: labels and ';' (Lua 5.2 only). */ | 2376 | /* Recursively parse trailing statements: labels and ';' (Lua 5.2 only). */ |
2407 | for (;;) { | 2377 | for (;;) { |
2408 | if (ls->token == TK_label) { | 2378 | if (ls->tok == TK_label) { |
2409 | synlevel_begin(ls); | 2379 | synlevel_begin(ls); |
2410 | parse_label(ls); | 2380 | parse_label(ls); |
2411 | synlevel_end(ls); | 2381 | synlevel_end(ls); |
2412 | } else if (LJ_52 && ls->token == ';') { | 2382 | } else if (LJ_52 && ls->tok == ';') { |
2413 | lj_lex_next(ls); | 2383 | lj_lex_next(ls); |
2414 | } else { | 2384 | } else { |
2415 | break; | 2385 | break; |
2416 | } | 2386 | } |
2417 | } | 2387 | } |
2418 | /* Trailing label is considered to be outside of scope. */ | 2388 | /* Trailing label is considered to be outside of scope. */ |
2419 | if (endofblock(ls->token) && ls->token != TK_until) | 2389 | if (parse_isend(ls->tok) && ls->tok != TK_until) |
2420 | ls->vstack[idx].slot = fs->bl->nactvar; | 2390 | ls->vstack[idx].slot = fs->bl->nactvar; |
2421 | gola_resolve(ls, fs->bl, idx); | 2391 | gola_resolve(ls, fs->bl, idx); |
2422 | } | 2392 | } |
@@ -2572,7 +2542,8 @@ static void parse_for_iter(LexState *ls, GCstr *indexname) | |||
2572 | lex_check(ls, TK_in); | 2542 | lex_check(ls, TK_in); |
2573 | line = ls->linenumber; | 2543 | line = ls->linenumber; |
2574 | assign_adjust(ls, 3, expr_list(ls, &e), &e); | 2544 | assign_adjust(ls, 3, expr_list(ls, &e), &e); |
2575 | bcreg_bump(fs, 3); /* The iterator needs another 3 slots (func + 2 args). */ | 2545 | /* The iterator needs another 3 [4] slots (func [pc] | state ctl). */ |
2546 | bcreg_bump(fs, 3+LJ_FR2); | ||
2576 | isnext = (nvars <= 5 && predict_next(ls, fs, exprpc)); | 2547 | isnext = (nvars <= 5 && predict_next(ls, fs, exprpc)); |
2577 | var_add(ls, 3); /* Hidden control variables. */ | 2548 | var_add(ls, 3); /* Hidden control variables. */ |
2578 | lex_check(ls, TK_do); | 2549 | lex_check(ls, TK_do); |
@@ -2600,9 +2571,9 @@ static void parse_for(LexState *ls, BCLine line) | |||
2600 | fscope_begin(fs, &bl, FSCOPE_LOOP); | 2571 | fscope_begin(fs, &bl, FSCOPE_LOOP); |
2601 | lj_lex_next(ls); /* Skip 'for'. */ | 2572 | lj_lex_next(ls); /* Skip 'for'. */ |
2602 | varname = lex_str(ls); /* Get first variable name. */ | 2573 | varname = lex_str(ls); /* Get first variable name. */ |
2603 | if (ls->token == '=') | 2574 | if (ls->tok == '=') |
2604 | parse_for_num(ls, varname, line); | 2575 | parse_for_num(ls, varname, line); |
2605 | else if (ls->token == ',' || ls->token == TK_in) | 2576 | else if (ls->tok == ',' || ls->tok == TK_in) |
2606 | parse_for_iter(ls, varname); | 2577 | parse_for_iter(ls, varname); |
2607 | else | 2578 | else |
2608 | err_syntax(ls, LJ_ERR_XFOR); | 2579 | err_syntax(ls, LJ_ERR_XFOR); |
@@ -2628,12 +2599,12 @@ static void parse_if(LexState *ls, BCLine line) | |||
2628 | BCPos flist; | 2599 | BCPos flist; |
2629 | BCPos escapelist = NO_JMP; | 2600 | BCPos escapelist = NO_JMP; |
2630 | flist = parse_then(ls); | 2601 | flist = parse_then(ls); |
2631 | while (ls->token == TK_elseif) { /* Parse multiple 'elseif' blocks. */ | 2602 | while (ls->tok == TK_elseif) { /* Parse multiple 'elseif' blocks. */ |
2632 | jmp_append(fs, &escapelist, bcemit_jmp(fs)); | 2603 | jmp_append(fs, &escapelist, bcemit_jmp(fs)); |
2633 | jmp_tohere(fs, flist); | 2604 | jmp_tohere(fs, flist); |
2634 | flist = parse_then(ls); | 2605 | flist = parse_then(ls); |
2635 | } | 2606 | } |
2636 | if (ls->token == TK_else) { /* Parse optional 'else' block. */ | 2607 | if (ls->tok == TK_else) { /* Parse optional 'else' block. */ |
2637 | jmp_append(fs, &escapelist, bcemit_jmp(fs)); | 2608 | jmp_append(fs, &escapelist, bcemit_jmp(fs)); |
2638 | jmp_tohere(fs, flist); | 2609 | jmp_tohere(fs, flist); |
2639 | lj_lex_next(ls); /* Skip 'else'. */ | 2610 | lj_lex_next(ls); /* Skip 'else'. */ |
@@ -2651,7 +2622,7 @@ static void parse_if(LexState *ls, BCLine line) | |||
2651 | static int parse_stmt(LexState *ls) | 2622 | static int parse_stmt(LexState *ls) |
2652 | { | 2623 | { |
2653 | BCLine line = ls->linenumber; | 2624 | BCLine line = ls->linenumber; |
2654 | switch (ls->token) { | 2625 | switch (ls->tok) { |
2655 | case TK_if: | 2626 | case TK_if: |
2656 | parse_if(ls, line); | 2627 | parse_if(ls, line); |
2657 | break; | 2628 | break; |
@@ -2710,7 +2681,7 @@ static void parse_chunk(LexState *ls) | |||
2710 | { | 2681 | { |
2711 | int islast = 0; | 2682 | int islast = 0; |
2712 | synlevel_begin(ls); | 2683 | synlevel_begin(ls); |
2713 | while (!islast && !endofblock(ls->token)) { | 2684 | while (!islast && !parse_isend(ls->tok)) { |
2714 | islast = parse_stmt(ls); | 2685 | islast = parse_stmt(ls); |
2715 | lex_opt(ls, ';'); | 2686 | lex_opt(ls, ';'); |
2716 | lua_assert(ls->fs->framesize >= ls->fs->freereg && | 2687 | lua_assert(ls->fs->framesize >= ls->fs->freereg && |
@@ -2745,7 +2716,7 @@ GCproto *lj_parse(LexState *ls) | |||
2745 | bcemit_AD(&fs, BC_FUNCV, 0, 0); /* Placeholder. */ | 2716 | bcemit_AD(&fs, BC_FUNCV, 0, 0); /* Placeholder. */ |
2746 | lj_lex_next(ls); /* Read-ahead first token. */ | 2717 | lj_lex_next(ls); /* Read-ahead first token. */ |
2747 | parse_chunk(ls); | 2718 | parse_chunk(ls); |
2748 | if (ls->token != TK_eof) | 2719 | if (ls->tok != TK_eof) |
2749 | err_token(ls, TK_eof); | 2720 | err_token(ls, TK_eof); |
2750 | pt = fs_finish(ls, ls->linenumber); | 2721 | pt = fs_finish(ls, ls->linenumber); |
2751 | L->top--; /* Drop chunkname. */ | 2722 | L->top--; /* Drop chunkname. */ |