lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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);