diff libinterp/corefcn/symscope.h @ 28026:262cdfc6faf9

allow reloading of handles to private functions (bug #57439) To allow a handle to a private function to reload the function it references after the function has been cleared and/or when the directory where the function was defined is no longer in the load path, store the directory in the symbol scope for the function, not just in the function itself. Also use the canonical directory name as the key for the private_function map in the load path. * fcn-info.cc (fcn_info::fcn_info_rep::load_private_function): Use canonical directory name as key in private_functions map. (fcn_info::fcn_info_rep::xfind): Get function file and directory names directly from the search scope. (fcn_info::fcn_info_rep::x_builtin_find): Likewise. * load-path.h, load-path.cc (load_path::M_FILE, load_path::OCT_FILE, load_path::MEX_FILE): Now public. (find_private_fcn_file): New static function. (load_path::package_info::remove): Use canonical directory name as key for private function map. (load_path::package_info::add_to_private_fcn_map): Likewise. (load_path::package_info::add_to_method_map): Likewise. (load_path::package_info::remove_private_fcn_map): Likewise. (load_path::package_info::find_private_fcn): Likewise. If function is not found in map, search filesystem. * symscope.h, symscope.cc (symbol_scope_rep::m_fcn_file_name, symbol_scope_rep::m_dir_name): New data members. (symbol_scope::dup): Copy them. (symbol_scope::cache_fcn_file_name, symbol_scope::cache_dir_name, symbol_scope::fcn_file_name, symbol_scope::dir_name, symbol_scope_rep::cache_fcn_file_name, symbol_scope_rep::cache_dir_name, symbol_scope_rep::fcn_file_name, symbol_scope_rep::dir_name): New functions. * oct-parse.yy (base_parser::make_script): Also cache file and directory names in script scope. (base_parser::finish_function): Also cache file and directory names in function scope. * pt-fcn-handle.cc (tree_anon_fcn_handle::evaluate): Also cache file and directory names in new scope associated with the anonymous function object.
author John W. Eaton <jwe@octave.org>
date Thu, 30 Jan 2020 15:12:52 -0500
parents bd51beb6205e
children 71c34141cc2d
line wrap: on
line diff
--- a/libinterp/corefcn/symscope.h	Wed Jan 29 08:20:55 2020 -0800
+++ b/libinterp/corefcn/symscope.h	Thu Jan 30 15:12:52 2020 -0500
@@ -40,7 +40,7 @@
 #include "oct-refcount.h"
 
 class tree_argument_list;
-class octave_user_function;
+class octave_user_code;
 
 #include "ov.h"
 #include "ovl.h"
@@ -67,9 +67,9 @@
 
     symbol_scope_rep (const std::string& name = "")
       : m_name (name), m_symbols (), m_subfunctions (),
-        m_persistent_values (), m_code (nullptr), m_parent (),
-        m_primary_parent (), m_children (), m_nesting_depth (0),
-        m_is_static (false)
+        m_persistent_values (), m_code (nullptr), m_fcn_file_name (),
+        m_dir_name (), m_parent (), m_primary_parent (), m_children (),
+        m_nesting_depth (0), m_is_static (false)
     {
       // All scopes have ans as the first symbol, initially undefined.
 
@@ -126,6 +126,8 @@
       new_sid->m_persistent_values = m_persistent_values;
       new_sid->m_subfunction_names = m_subfunction_names;
       new_sid->m_code = m_code;
+      new_sid->m_fcn_file_name = m_fcn_file_name;
+      new_sid->m_dir_name = m_dir_name;
       new_sid->m_parent = m_parent;
       new_sid->m_primary_parent = m_primary_parent;
       new_sid->m_children = m_children;
@@ -252,6 +254,17 @@
 
     void set_primary_parent (const std::shared_ptr<symbol_scope_rep>& parent);
 
+    void cache_fcn_file_name (const std::string& name)
+    {
+      m_fcn_file_name = name;
+    }
+
+    void cache_dir_name (const std::string& name);
+
+    std::string fcn_file_name (void) const { return m_fcn_file_name; }
+
+    std::string dir_name (void) const { return m_dir_name; }
+
     bool is_relative (const std::shared_ptr<symbol_scope_rep>& scope) const;
 
     void update_nest (void);
@@ -300,6 +313,14 @@
 
     octave_user_code *m_code;
 
+    //! The file name associated with m_code.
+
+    std::string m_fcn_file_name;
+
+    //! The directory associated with m_code.
+
+    std::string m_dir_name;
+
     //! Parent of nested function (may be null).
 
     std::weak_ptr<symbol_scope_rep> m_parent;
@@ -550,6 +571,28 @@
         m_rep->set_primary_parent (p.get_rep ());
     }
 
+    void cache_fcn_file_name (const std::string& name)
+    {
+      if (m_rep)
+        m_rep->cache_fcn_file_name (name);
+    }
+
+    void cache_dir_name (const std::string& name)
+    {
+      if (m_rep)
+        m_rep->cache_dir_name (name);
+    }
+
+    std::string fcn_file_name (void) const
+    {
+      return m_rep ? m_rep->fcn_file_name () : "";
+    }
+
+    std::string dir_name (void) const
+    {
+      return m_rep ? m_rep->dir_name () : "";
+    }
+
     bool is_relative (const symbol_scope& scope) const
     {
       return m_rep ? m_rep->is_relative (scope.get_rep ()) : false;