diff options
Diffstat (limited to 'src/lj_parse.c')
-rw-r--r-- | src/lj_parse.c | 34 |
1 files changed, 6 insertions, 28 deletions
diff --git a/src/lj_parse.c b/src/lj_parse.c index 70097598..e326432a 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c | |||
@@ -1517,23 +1517,11 @@ static void fs_fixup_var(LexState *ls, GCproto *pt, uint8_t *p, size_t ofsvar) | |||
1517 | 1517 | ||
1518 | #endif | 1518 | #endif |
1519 | 1519 | ||
1520 | /* Check if bytecode op returns. */ | ||
1521 | static int bcopisret(BCOp op) | ||
1522 | { | ||
1523 | switch (op) { | ||
1524 | case BC_CALLMT: case BC_CALLT: | ||
1525 | case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1: | ||
1526 | return 1; | ||
1527 | default: | ||
1528 | return 0; | ||
1529 | } | ||
1530 | } | ||
1531 | |||
1532 | /* Fixup return instruction for prototype. */ | 1520 | /* Fixup return instruction for prototype. */ |
1533 | static void fs_fixup_ret(FuncState *fs) | 1521 | static void fs_fixup_ret(FuncState *fs) |
1534 | { | 1522 | { |
1535 | BCPos lastpc = fs->pc; | 1523 | BCPos lastpc = fs->pc; |
1536 | if (lastpc <= fs->lasttarget || !bcopisret(bc_op(fs->bcbase[lastpc-1].ins))) { | 1524 | if (lastpc <= fs->lasttarget || !bc_isret_or_tail(bc_op(fs->bcbase[lastpc-1].ins))) { |
1537 | if ((fs->bl->flags & FSCOPE_UPVAL)) | 1525 | if ((fs->bl->flags & FSCOPE_UPVAL)) |
1538 | bcemit_AJ(fs, BC_UCLO, 0, 0); | 1526 | bcemit_AJ(fs, BC_UCLO, 0, 0); |
1539 | bcemit_AD(fs, BC_RET0, 0, 1); /* Need final return. */ | 1527 | bcemit_AD(fs, BC_RET0, 0, 1); /* Need final return. */ |
@@ -1725,7 +1713,7 @@ static void expr_table(LexState *ls, ExpDesc *e) | |||
1725 | FuncState *fs = ls->fs; | 1713 | FuncState *fs = ls->fs; |
1726 | BCLine line = ls->linenumber; | 1714 | BCLine line = ls->linenumber; |
1727 | GCtab *t = NULL; | 1715 | GCtab *t = NULL; |
1728 | int vcall = 0, needarr = 0, fixt = 0; | 1716 | int vcall = 0, needarr = 0; |
1729 | uint32_t narr = 1; /* First array index. */ | 1717 | uint32_t narr = 1; /* First array index. */ |
1730 | uint32_t nhash = 0; /* Number of hash entries. */ | 1718 | uint32_t nhash = 0; /* Number of hash entries. */ |
1731 | BCReg freg = fs->freereg; | 1719 | BCReg freg = fs->freereg; |
@@ -1769,9 +1757,10 @@ static void expr_table(LexState *ls, ExpDesc *e) | |||
1769 | lj_gc_anybarriert(fs->L, t); | 1757 | lj_gc_anybarriert(fs->L, t); |
1770 | if (expr_isk_nojump(&val)) { /* Add const key/value to template table. */ | 1758 | if (expr_isk_nojump(&val)) { /* Add const key/value to template table. */ |
1771 | expr_kvalue(fs, v, &val); | 1759 | expr_kvalue(fs, v, &val); |
1772 | } else { /* Otherwise create dummy string key (avoids lj_tab_newkey). */ | 1760 | /* Mark nil value with table value itself to preserve the key. */ |
1773 | settabV(fs->L, v, t); /* Preserve key with table itself as value. */ | 1761 | if (key.k == VKSTR && tvisnil(v)) settabV(fs->L, v, t); |
1774 | fixt = 1; /* Fix this later, after all resizes. */ | 1762 | } else { /* Preserve the key for the following non-const store. */ |
1763 | settabV(fs->L, v, t); | ||
1775 | goto nonconst; | 1764 | goto nonconst; |
1776 | } | 1765 | } |
1777 | } else { | 1766 | } else { |
@@ -1813,17 +1802,6 @@ static void expr_table(LexState *ls, ExpDesc *e) | |||
1813 | } else { | 1802 | } else { |
1814 | if (needarr && t->asize < narr) | 1803 | if (needarr && t->asize < narr) |
1815 | lj_tab_reasize(fs->L, t, narr-1); | 1804 | lj_tab_reasize(fs->L, t, narr-1); |
1816 | if (fixt) { /* Fix value for dummy keys in template table. */ | ||
1817 | Node *node = noderef(t->node); | ||
1818 | uint32_t i, hmask = t->hmask; | ||
1819 | for (i = 0; i <= hmask; i++) { | ||
1820 | Node *n = &node[i]; | ||
1821 | if (tvistab(&n->val)) { | ||
1822 | lj_assertFS(tabV(&n->val) == t, "bad dummy key in template table"); | ||
1823 | setnilV(&n->val); /* Turn value into nil. */ | ||
1824 | } | ||
1825 | } | ||
1826 | } | ||
1827 | lj_gc_check(fs->L); | 1805 | lj_gc_check(fs->L); |
1828 | } | 1806 | } |
1829 | } | 1807 | } |