aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2025-03-10 02:56:07 +0100
committerMike Pall <mike>2025-03-10 02:56:07 +0100
commit84cb21ffaf648b472ff3884556e2c413e8abe179 (patch)
treebf63bb6de4b4893225cecc6023f6c1e90586c28b /src
parent4f2bb199fe7138247e0b075c886c9e9197cf0271 (diff)
downloadluajit-84cb21ffaf648b472ff3884556e2c413e8abe179.tar.gz
luajit-84cb21ffaf648b472ff3884556e2c413e8abe179.tar.bz2
luajit-84cb21ffaf648b472ff3884556e2c413e8abe179.zip
REVERT: Change handling of nil value markers in template tables.
Diffstat (limited to 'src')
-rw-r--r--src/lj_bcread.c10
-rw-r--r--src/lj_bcwrite.c8
-rw-r--r--src/lj_opt_fold.c6
-rw-r--r--src/lj_opt_mem.c4
-rw-r--r--src/lj_parse.c20
-rw-r--r--src/lj_tab.c1
6 files changed, 25 insertions, 24 deletions
diff --git a/src/lj_bcread.c b/src/lj_bcread.c
index 37e909b3..ee7d7c18 100644
--- a/src/lj_bcread.c
+++ b/src/lj_bcread.c
@@ -179,7 +179,7 @@ static const void *bcread_varinfo(GCproto *pt)
179} 179}
180 180
181/* Read a single constant key/value of a template table. */ 181/* Read a single constant key/value of a template table. */
182static void bcread_ktabk(LexState *ls, TValue *o, GCtab *t) 182static void bcread_ktabk(LexState *ls, TValue *o)
183{ 183{
184 MSize tp = bcread_uleb128(ls); 184 MSize tp = bcread_uleb128(ls);
185 if (tp >= BCDUMP_KTAB_STR) { 185 if (tp >= BCDUMP_KTAB_STR) {
@@ -191,8 +191,6 @@ static void bcread_ktabk(LexState *ls, TValue *o, GCtab *t)
191 } else if (tp == BCDUMP_KTAB_NUM) { 191 } else if (tp == BCDUMP_KTAB_NUM) {
192 o->u32.lo = bcread_uleb128(ls); 192 o->u32.lo = bcread_uleb128(ls);
193 o->u32.hi = bcread_uleb128(ls); 193 o->u32.hi = bcread_uleb128(ls);
194 } else if (tp == BCDUMP_KTAB_NIL) { /* Restore nil value marker. */
195 settabV(ls->L, o, t);
196 } else { 194 } else {
197 lj_assertLS(tp <= BCDUMP_KTAB_TRUE, "bad constant type %d", tp); 195 lj_assertLS(tp <= BCDUMP_KTAB_TRUE, "bad constant type %d", tp);
198 setpriV(o, ~tp); 196 setpriV(o, ~tp);
@@ -209,15 +207,15 @@ static GCtab *bcread_ktab(LexState *ls)
209 MSize i; 207 MSize i;
210 TValue *o = tvref(t->array); 208 TValue *o = tvref(t->array);
211 for (i = 0; i < narray; i++, o++) 209 for (i = 0; i < narray; i++, o++)
212 bcread_ktabk(ls, o, t); 210 bcread_ktabk(ls, o);
213 } 211 }
214 if (nhash) { /* Read hash entries. */ 212 if (nhash) { /* Read hash entries. */
215 MSize i; 213 MSize i;
216 for (i = 0; i < nhash; i++) { 214 for (i = 0; i < nhash; i++) {
217 TValue key; 215 TValue key;
218 bcread_ktabk(ls, &key, t); 216 bcread_ktabk(ls, &key);
219 lj_assertLS(!tvisnil(&key), "nil key"); 217 lj_assertLS(!tvisnil(&key), "nil key");
220 bcread_ktabk(ls, lj_tab_set(ls->L, t, &key), t); 218 bcread_ktabk(ls, lj_tab_set(ls->L, t, &key));
221 } 219 }
222 } 220 }
223 return t; 221 return t;
diff --git a/src/lj_bcwrite.c b/src/lj_bcwrite.c
index ec6f13c8..de200ef4 100644
--- a/src/lj_bcwrite.c
+++ b/src/lj_bcwrite.c
@@ -71,8 +71,6 @@ static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow)
71 *p++ = BCDUMP_KTAB_NUM; 71 *p++ = BCDUMP_KTAB_NUM;
72 p = lj_strfmt_wuleb128(p, o->u32.lo); 72 p = lj_strfmt_wuleb128(p, o->u32.lo);
73 p = lj_strfmt_wuleb128(p, o->u32.hi); 73 p = lj_strfmt_wuleb128(p, o->u32.hi);
74 } else if (tvistab(o)) { /* Write the nil value marker as a nil. */
75 *p++ = BCDUMP_KTAB_NIL;
76 } else { 74 } else {
77 lj_assertBCW(tvispri(o), "unhandled type %d", itype(o)); 75 lj_assertBCW(tvispri(o), "unhandled type %d", itype(o));
78 *p++ = BCDUMP_KTAB_NIL+~itype(o); 76 *p++ = BCDUMP_KTAB_NIL+~itype(o);
@@ -135,7 +133,7 @@ static void bcwrite_ktab_sorted_hash(BCWriteCtx *ctx, Node *node, MSize nhash)
135 TValue **heap = ctx->heap; 133 TValue **heap = ctx->heap;
136 MSize i = nhash; 134 MSize i = nhash;
137 for (;; node--) { /* Build heap. */ 135 for (;; node--) { /* Build heap. */
138 if (!tvisnil(&node->val)) { 136 if (!tvisnil(&node->key)) {
139 bcwrite_ktabk_heap_insert(heap, --i, nhash, &node->key); 137 bcwrite_ktabk_heap_insert(heap, --i, nhash, &node->key);
140 if (i == 0) break; 138 if (i == 0) break;
141 } 139 }
@@ -165,7 +163,7 @@ static void bcwrite_ktab(BCWriteCtx *ctx, char *p, const GCtab *t)
165 MSize i, hmask = t->hmask; 163 MSize i, hmask = t->hmask;
166 Node *node = noderef(t->node); 164 Node *node = noderef(t->node);
167 for (i = 0; i <= hmask; i++) 165 for (i = 0; i <= hmask; i++)
168 nhash += !tvisnil(&node[i].val); 166 nhash += !tvisnil(&node[i].key);
169 } 167 }
170 /* Write number of array slots and hash slots. */ 168 /* Write number of array slots and hash slots. */
171 p = lj_strfmt_wuleb128(p, narray); 169 p = lj_strfmt_wuleb128(p, narray);
@@ -186,7 +184,7 @@ static void bcwrite_ktab(BCWriteCtx *ctx, char *p, const GCtab *t)
186 } else { 184 } else {
187 MSize i = nhash; 185 MSize i = nhash;
188 for (;; node--) 186 for (;; node--)
189 if (!tvisnil(&node->val)) { 187 if (!tvisnil(&node->key)) {
190 bcwrite_ktabk(ctx, &node->key, 0); 188 bcwrite_ktabk(ctx, &node->key, 0);
191 bcwrite_ktabk(ctx, &node->val, 1); 189 bcwrite_ktabk(ctx, &node->val, 1);
192 if (--i == 0) break; 190 if (--i == 0) break;
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c
index 6fdf4566..36aacebb 100644
--- a/src/lj_opt_fold.c
+++ b/src/lj_opt_fold.c
@@ -2217,11 +2217,9 @@ LJFOLD(HREF TDUP KNUM)
2217LJFOLDF(fwd_href_tdup) 2217LJFOLDF(fwd_href_tdup)
2218{ 2218{
2219 TValue keyv; 2219 TValue keyv;
2220 cTValue *val;
2221 lj_ir_kvalue(J->L, &keyv, fright); 2220 lj_ir_kvalue(J->L, &keyv, fright);
2222 val = lj_tab_get(J->L, ir_ktab(IR(fleft->op1)), &keyv); 2221 if (lj_tab_get(J->L, ir_ktab(IR(fleft->op1)), &keyv) == niltvg(J2G(J)) &&
2223 /* Check for either nil or the nil value marker in the template table. */ 2222 lj_opt_fwd_href_nokey(J))
2224 if ((tvisnil(val) || tvistab(val)) && lj_opt_fwd_href_nokey(J))
2225 return lj_ir_kkptr(J, niltvg(J2G(J))); 2223 return lj_ir_kkptr(J, niltvg(J2G(J)));
2226 return NEXTFOLD; 2224 return NEXTFOLD;
2227} 2225}
diff --git a/src/lj_opt_mem.c b/src/lj_opt_mem.c
index 6f956b37..8cacfcfe 100644
--- a/src/lj_opt_mem.c
+++ b/src/lj_opt_mem.c
@@ -233,9 +233,7 @@ static TRef fwd_ahload(jit_State *J, IRRef xref)
233 return lj_ir_knum_u64(J, tv->u64); 233 return lj_ir_knum_u64(J, tv->u64);
234 else if (tvisint(tv)) 234 else if (tvisint(tv))
235 return lj_ir_kint(J, intV(tv)); 235 return lj_ir_kint(J, intV(tv));
236 else if (tvistab(tv)) /* Template table nil value marker. */ 236 else if (tvisgcv(tv))
237 return TREF_NIL;
238 else if (tvisstr(tv))
239 return lj_ir_kstr(J, strV(tv)); 237 return lj_ir_kstr(J, strV(tv));
240 } 238 }
241 /* Othwerwise: don't intern as a constant. */ 239 /* Othwerwise: don't intern as a constant. */
diff --git a/src/lj_parse.c b/src/lj_parse.c
index f4116380..70097598 100644
--- a/src/lj_parse.c
+++ b/src/lj_parse.c
@@ -1725,7 +1725,7 @@ static void expr_table(LexState *ls, ExpDesc *e)
1725 FuncState *fs = ls->fs; 1725 FuncState *fs = ls->fs;
1726 BCLine line = ls->linenumber; 1726 BCLine line = ls->linenumber;
1727 GCtab *t = NULL; 1727 GCtab *t = NULL;
1728 int vcall = 0, needarr = 0; 1728 int vcall = 0, needarr = 0, fixt = 0;
1729 uint32_t narr = 1; /* First array index. */ 1729 uint32_t narr = 1; /* First array index. */
1730 uint32_t nhash = 0; /* Number of hash entries. */ 1730 uint32_t nhash = 0; /* Number of hash entries. */
1731 BCReg freg = fs->freereg; 1731 BCReg freg = fs->freereg;
@@ -1769,10 +1769,9 @@ static void expr_table(LexState *ls, ExpDesc *e)
1769 lj_gc_anybarriert(fs->L, t); 1769 lj_gc_anybarriert(fs->L, t);
1770 if (expr_isk_nojump(&val)) { /* Add const key/value to template table. */ 1770 if (expr_isk_nojump(&val)) { /* Add const key/value to template table. */
1771 expr_kvalue(fs, v, &val); 1771 expr_kvalue(fs, v, &val);
1772 /* Mark nil value with table value itself to preserve the key. */ 1772 } else { /* Otherwise create dummy string key (avoids lj_tab_newkey). */
1773 if (key.k == VKSTR && tvisnil(v)) settabV(fs->L, v, t); 1773 settabV(fs->L, v, t); /* Preserve key with table itself as value. */
1774 } else { /* Preserve the key for the following non-const store. */ 1774 fixt = 1; /* Fix this later, after all resizes. */
1775 settabV(fs->L, v, t);
1776 goto nonconst; 1775 goto nonconst;
1777 } 1776 }
1778 } else { 1777 } else {
@@ -1814,6 +1813,17 @@ static void expr_table(LexState *ls, ExpDesc *e)
1814 } else { 1813 } else {
1815 if (needarr && t->asize < narr) 1814 if (needarr && t->asize < narr)
1816 lj_tab_reasize(fs->L, t, narr-1); 1815 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 }
1817 lj_gc_check(fs->L); 1827 lj_gc_check(fs->L);
1818 } 1828 }
1819} 1829}
diff --git a/src/lj_tab.c b/src/lj_tab.c
index 62e33611..2d080552 100644
--- a/src/lj_tab.c
+++ b/src/lj_tab.c
@@ -194,7 +194,6 @@ GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt)
194 Node *next = nextnode(kn); 194 Node *next = nextnode(kn);
195 /* Don't use copyTV here, since it asserts on a copy of a dead key. */ 195 /* Don't use copyTV here, since it asserts on a copy of a dead key. */
196 n->val = kn->val; n->key = kn->key; 196 n->val = kn->val; n->key = kn->key;
197 if (tvistab(&n->val)) setnilV(&n->val); /* Replace nil value marker. */
198 setmref(n->next, next == NULL? next : (Node *)((char *)next + d)); 197 setmref(n->next, next == NULL? next : (Node *)((char *)next + d));
199 } 198 }
200 } 199 }