Mercurial > octave
changeset 24031:ef85638c605a
also cache parent_function in symbol_table scope
Inside a symbol table scope, we currently store a pointer to the
parent scope (if it exists), but this is not sufficient to prevent the
parent scope from being deleted. For example, this can happen when a
function that contains an anonymous function definition is deleted.
If the anonymous function remains accessible, then resolving any
symbols that it references may fail when it is called. Caching the
parent function avoids this problem as it increments the reference
count for the function, and that will prevent the scope object from
being deleted.
* symtab.cc (symbol_table::scope::set_parent): Also cache parent
function if it exists.
* symtab.h (symbol_table::scope::m_parent): New data member.
(symbol_table::scope::parent_fcn): New function.
(symbol_table::scope::dup): Also copy m_parent_fcn.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 08 Sep 2017 18:15:50 -0400 |
parents | ec3d37eeafa2 |
children | c2ef0eddf6bc |
files | libinterp/corefcn/symtab.cc libinterp/corefcn/symtab.h |
diffstat | 2 files changed, 22 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/symtab.cc Thu Aug 31 21:10:56 2017 +0200 +++ b/libinterp/corefcn/symtab.cc Fri Sep 08 18:15:50 2017 -0400 @@ -1803,6 +1803,23 @@ } void + symbol_table::scope::set_parent (scope *p) + { + m_parent = p; + + if (m_parent) + { + // If m_parent is the top-level scope, there will be no parent + // function. + + octave_function *ov_fcn = m_parent->function (); + + if (ov_fcn) + m_parent_fcn = octave_value (ov_fcn, true); + } + } + + void symbol_table::scope::update_nest (void) { if (m_parent)
--- a/libinterp/corefcn/symtab.h Thu Aug 31 21:10:56 2017 +0200 +++ b/libinterp/corefcn/symtab.h Fri Sep 08 18:15:50 2017 -0400 @@ -1567,7 +1567,7 @@ scope (const std::string& name = "") : m_name (name), m_symbols (), m_persistent_symbols (), m_subfunctions (), - m_fcn (nullptr), m_parent (nullptr), m_children (), m_is_nested (false), + m_fcn (nullptr), m_parent (nullptr), m_parent_fcn (), m_children (), m_is_nested (false), m_is_static (false), m_context (0) { } @@ -1593,6 +1593,7 @@ void mark_static (void) { m_is_static = true; } scope * parent_scope (void) const { return m_parent; } + octave_value parent_fcn (void) const { return m_parent_fcn; } scope * dup (void) const { @@ -1602,6 +1603,7 @@ new_sid->insert_symbol_record (nm_sr.second.dup (new_sid)); new_sid->m_parent = m_parent; + new_sid->m_parent_fcn = m_parent_fcn; return new_sid; } @@ -2034,7 +2036,7 @@ void set_function (octave_user_function *fcn) { m_fcn = fcn; } - void set_parent (scope *p) { m_parent = p; } + void set_parent (scope *p); void update_nest (void); @@ -2061,6 +2063,7 @@ // Parent of nested function (may be null). scope *m_parent; + octave_value m_parent_fcn; // Child nested functions. std::vector<scope*> m_children;