diff libinterp/parse-tree/pt-anon-scopes.h @ 26661:cf9e10ce3351

move variable values from symbol_record objects to stack_frame objects Apologies for the massive commit. I see no way to untangle these changes into a set of smaller incremental changes in a way that would be more useful. Previously, handling data for recursive function calls was managed by a stack of values in the symbol_record class and an auxiliary integer variable was used for managing the recursion depth (context_id). Now, values for local variables are in the stack_frame class and recursion is handled naturally by the call_stack as a new stack frame is added to the call_stack object for any call to a function or a script. Values for internal function call information (nargin, nargout, etc.) are now stored specially in the stack_frame object. Values for global variables are now stored in a map in the call_stack object. Values for persistent variables are stored in the corresponding octave_user_function object. Access to non-local variables inside nested functions is managed through pointers to stack_frame objects for the parent function scopes. The new implementation more closely resembles the techniques described in standard compiler literature. These changes should make it easier to create proper closures and finally solve bug #39257 (handles to nested functions are not yet supported). They may also make it easier to implement JIT compiler, though that is probably still a long way off. The new stack-frame.h file has some details about the new implementation of stack frames that should help in understanding how things work now. Describing each change to each file and function will probably not provide much greater understanding of the changes and would be quite tedious to write so I am omitting them.
author John W. Eaton <jwe@octave.org>
date Mon, 28 Jan 2019 18:01:46 +0000
parents 00f796120a6d
children 581d01526b34
line wrap: on
line diff
--- a/libinterp/parse-tree/pt-anon-scopes.h	Sat Jan 26 15:53:29 2019 +0000
+++ b/libinterp/parse-tree/pt-anon-scopes.h	Mon Jan 28 18:01:46 2019 +0000
@@ -24,8 +24,10 @@
 #if !defined (octave_pt_anon_scopes_h)
 #define octave_pt_anon_scopes_h 1
 
+#include <set>
+#include <string>
+
 #include "pt-walk.h"
-#include "ov-usr-fcn.h"
 
 namespace octave
 {
@@ -37,33 +39,9 @@
   {
   public:
 
-    tree_anon_scopes (void) : scopes (), merged_tables () { }
-
-    tree_anon_scopes (octave_user_function *);
-
-    tree_anon_scopes& operator = (tree_anon_scopes&& tas)
-    {
-      scopes = std::move (tas.scopes);
-      merged_tables = std::move (tas.merged_tables);
-      return *this;
-    }
-
-    typedef std::map<std::string, symbol_record> symrec_map;
+    tree_anon_scopes (void) = delete;
 
-    symrec_map::const_iterator begin (void)
-    {
-      return merged_tables.cbegin ();
-    }
-
-    symrec_map::const_iterator end (void)
-    {
-      return merged_tables.cend ();
-    }
-
-    unsigned int symrec_map_size (void)
-    {
-      return merged_tables.size ();
-    }
+    tree_anon_scopes (tree_anon_fcn_handle& anon_fh);
 
     // No copying!
 
@@ -71,7 +49,11 @@
 
     tree_anon_scopes& operator = (const tree_anon_scopes&) = delete;
 
-    ~tree_anon_scopes (void) { }
+    ~tree_anon_scopes (void) = default;
+
+    std::set<std::string> fcn_parameters (void) const { return m_params; }
+
+    std::set<std::string> free_variables (void) const { return m_vars; }
 
     // The following methods, though public, don't belong to the
     // intended user interface of this class.
@@ -160,27 +142,11 @@
 
   private:
 
-    void stash_scope_if_valid (const symbol_scope& sc)
-    {
-      if (sc)
-        scopes.push_back (sc);
-      else
-        error ("internal error, invalid scope");
-    }
+    // Variable names that are function parameters.
+    std::set<std::string> m_params;
 
-    // The scope of this anonymous function and the collected scopes
-    // of all anonymous functions whose definitions are nested in the
-    // current anonymous function definition.
-
-    std::vector<symbol_scope> scopes;
-
-    // Symbol records of all collected scopes are merged over variable names.
-
-    typedef std::list<symbol_record> symrec_list;
-
-    void merge_tables (void);
-
-    symrec_map merged_tables;
+    // Other variable names.
+    std::set<std::string> m_vars;
   };
 }