[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: LUA fails to parse expression with big and nested lists.
- From: Andrey Dobrovolsky <ken@...>
- Date: Sat, 7 Oct 2023 13:25:24 +0300
Hi,
The previous patch works nice with the tables using pure list
constructors, but nested tables as the named fields still may cause
register pool exhaustion. Modification of the recfield() function is
necessary to force list flushing and freeing the registers allocated.
The patch for lua-5.4.6 attached.
Changes against the original lua-5.4.6:
readelf -s liblua.a | grep recfield
60: 00003180 301 FUNC LOCAL DEFAULT 7 recfield
readelf -s liblua.a | grep recfield
60: 00002ef0 359 FUNC LOCAL DEFAULT 7 recfield
readelf -s liblua.a | grep constructor
58: 000032b0 670 FUNC LOCAL DEFAULT 7 constructor
readelf -s liblua.a | grep constructor
58: 00003060 715 FUNC LOCAL DEFAULT 7 constructor
Best regards!
Andrey Dobrovolsky
--- lparser.c.orig 2023-05-02 23:02:30.000000000 +0300
+++ lparser.c 2023-10-07 12:17:02.917504205 +0300
@@ -847,8 +847,14 @@
static void recfield (LexState *ls, ConsControl *cc) {
/* recfield -> (NAME | '['exp']') = exp */
FuncState *fs = ls->fs;
- int reg = ls->fs->freereg;
+ int reg;
expdesc tab, key, val;
+ if (cc->tostore){
+ luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */
+ cc->na += cc->tostore;
+ cc->tostore = 0; /* no more items pending */
+ }
+ reg = ls->fs->freereg;
if (ls->t.token == TK_NAME) {
checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
codename(ls, &key);
@@ -865,11 +871,11 @@
}
-static void closelistfield (FuncState *fs, ConsControl *cc) {
+static void closelistfield (FuncState *fs, ConsControl *cc, int flush) {
if (cc->v.k == VVOID) return; /* there is no list item */
luaK_exp2nextreg(fs, &cc->v);
cc->v.k = VVOID;
- if (cc->tostore == LFIELDS_PER_FLUSH) {
+ if ((cc->tostore == LFIELDS_PER_FLUSH) || flush){
luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */
cc->na += cc->tostore;
cc->tostore = 0; /* no more items pending */
@@ -939,7 +945,7 @@
do {
lua_assert(cc.v.k == VVOID || cc.tostore > 0);
if (ls->t.token == '}') break;
- closelistfield(fs, &cc);
+ closelistfield(fs, &cc, ls->t.token == '{');
field(ls, &cc);
} while (testnext(ls, ',') || testnext(ls, ';'));
check_match(ls, '}', '{', line);