On Thu, Aug 29, 2019 at 2:42 PM Marcel Fabian Krüger <tex@2krueger.de> wrote:
Hello,

in current versions of LuaTeX, `runtoks` does not preserve token lists
of ongoing assignments. Therefore running `runtoks` inside of `\edef`
or similar replace the definition with the defined value of the last
inner assignment.

For example:

\toks0{\def\innermacro{inner}}
\edef\outermacro{outer\directlua{tex.runtoks(0)}}
\show\outermacro
\bye

in plain TeX should show

> \outermacro=macro:
->outer.

but currently does show

> \outermacro=macro:
->inner.

instead.

(As a side effect the reference count isn't updated, so for example

\toks0{\def\innermacro{inner}\let\innermacro\undefined}
\edef\outermacro{outer\directlua{tex.runtoks(0)}}
\show\outermacro
\bye

starts printing hyphenation patterns on my system.)

This can be fixed by saving scanner_status, warning_index and def_ref
when entering local_control:

diff --git a/source/texk/web2c/luatexdir/tex/maincontrol.c b/source/texk/web2c/luatexdir/tex/maincontrol.c
index b01931dd1..284fb0ae3 100644
--- a/source/texk/web2c/luatexdir/tex/maincontrol.c
+++ b/source/texk/web2c/luatexdir/tex/maincontrol.c
@@ -1055,6 +1055,10 @@ extern void local_control_message(const char *s)
 void local_control(void)
 {
     int ll = local_level;
+    int save_scanner_status = scanner_status;
+    halfword save_def_ref = def_ref;
+    halfword save_warning_index = warning_index;
+
     main_control_state = goto_next;
     local_level += 1;
     while (1) {
@@ -1077,14 +1081,17 @@ void local_control(void)
             if (tracing_nesting_par > 2) {
                 local_control_message("leaving due to level change");
             }
-            return ;
+            break;
         } else if (main_control_state == goto_return) {
             if (tracing_nesting_par > 2) {
                 local_control_message("leaving due to triggering");
             }
-            return;
+            break;
         }
     }
+    scanner_status = save_scanner_status;
+    def_ref = save_def_ref;
+    warning_index = save_warning_index;
     return;
 }


we are seeing it. 

--
luigi