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.c34
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. */
1521static 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. */
1533static void fs_fixup_ret(FuncState *fs) 1521static 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}