From the beginning, Octave has stored values in the symbol table. This
simplistic model initially did not work correctly for recursive function
calls. To properly handle recursion, each symbol_record (the object
corresponding to a single variable in the scope of a script or function)
was eventually augmented to maintain a stack of values. This worked,
more or less, but was quite messy. Accessing values in recursive
functions was cumbersome and required managing a "context" variable to
say which element of the stack to access.
To fix this problem, I recently began a significant refactoring to move
the storage of values from the symbol table to the call stack. This
makes much more sense and is consistent with the way I understand other
interpreters and complied languages typically work. With the new
approach for storing values, accessing data from non-local scopes
(nested functions accessing variables from parent functions) and data in
parent stack frames is much simpler. Creating proper closures should be
much more manageable, and should allow bug #39257 (handles to nested
functions are not yet supported) to be fixed (finally!).
The patches for these changes are on the jwe-call-stack-refactor
bookmark in the mercurial archive publicly accessible here:
There are approximately 80 smaller changesets that make up the complete
set of changes. These changes are not all self-contained or rational as
many were made at temporary checkpoints during development. If merged
together, the resulting diff is about 12,000 lines. I'm inclined to
apply it as one large changeset since at this point I don't know how to
break it up into smaller chunks that make sense.
Some details about the implementation are included at the top of the
stack-frame.h file and before each class declaration in that file.
One way or another, I'd like to merge these changes with the default
branch soon so they can be thoroughly tested before Octave 6 is released
sometime later in 2019 or early 2020.