# HG changeset patch
# User Petter Tomner <tomner@kth.se>
# Date 1640211727 -3600
#      Wed Dec 22 23:22:07 2021 +0100
# Node ID 1a3cd0f2e0963e2f733a0cd315d3b38fd4bfcd7d
# Parent  9c46aea521e981c1b21e3c672c2e8bac22d5f8b2
interpreter: Replace some unwind protect with custom classes

Use custom classes for doing unwind protection to avoid function
object allocation on the heap.

libinterp/parse-tree/
	* pt-assign.cc: Use custom unwind class
	* pt-eval.h: Define custom unwind classes
	* pt-idx.cc: Use custom unwind class

diff -r 9c46aea521e9 -r 1a3cd0f2e096 libinterp/parse-tree/pt-assign.cc
--- a/libinterp/parse-tree/pt-assign.cc	Tue Dec 21 22:46:12 2021 +0100
+++ b/libinterp/parse-tree/pt-assign.cc	Wed Dec 22 23:22:07 2021 +0100
@@ -91,10 +91,8 @@
             tiny_vector<octave_lvalue> lvalue_vec;
             lvalue_vec.push_back (ult);
 
-            unwind_action act ([&tw] (const tiny_vector<octave_lvalue> *lvl)
-                               {
-                                 tw.set_lvalue_list (lvl);
-                               }, tw.lvalue_list ());
+            unwind_reset_tw_lvalue_list obj {&tw, tw.lvalue_list ()};
+
             tw.set_lvalue_list (&lvalue_vec);
 
             if (ult.numel () != 1)
@@ -188,10 +186,8 @@
       {
         tiny_vector<octave_lvalue> lvalue_list = tw.make_lvalue_list (m_lhs);
 
-        unwind_action act ([&tw] (const tiny_vector<octave_lvalue> *lvl)
-                           {
-                             tw.set_lvalue_list (lvl);
-                           }, tw.lvalue_list ());
+        unwind_reset_tw_lvalue_list obj {&tw, tw.lvalue_list ()};
+
         tw.set_lvalue_list (&lvalue_list);
 
         octave_idx_type n_out = 0;
diff -r 9c46aea521e9 -r 1a3cd0f2e096 libinterp/parse-tree/pt-eval.h
--- a/libinterp/parse-tree/pt-eval.h	Tue Dec 21 22:46:12 2021 +0100
+++ b/libinterp/parse-tree/pt-eval.h	Wed Dec 22 23:22:07 2021 +0100
@@ -992,6 +992,49 @@
     int m_num_indices;
   };
 
+  // For reseting the tw lvalue list when the object goes
+  // out of scope.
+  class unwind_reset_tw_lvalue_list
+  {
+  public:
+    unwind_reset_tw_lvalue_list (tree_evaluator *tw,
+                  const tiny_vector<octave_lvalue> *lvl)
+      : m_tw (tw), m_lvl (lvl) {}
+
+    ~unwind_reset_tw_lvalue_list ()
+    {
+      m_tw->set_lvalue_list (m_lvl);
+    }
+
+  private:
+    tree_evaluator *m_tw;
+    const tiny_vector<octave_lvalue> *m_lvl;
+  };
+
+  class unwind_reset_tw_indexed_obj
+  {
+  public:
+    unwind_reset_tw_indexed_obj (tree_evaluator *tw,
+                                 const octave_value& val,
+                                 const std::string& index_type,
+                                 const std::list<octave_value_list>& index_list)
+      : m_tw (tw), m_val (val),
+        m_index_type (index_type),
+        m_index_list (index_list) {}
+
+    ~unwind_reset_tw_indexed_obj ()
+    {
+      m_tw->set_indexed_object (m_val);
+      m_tw->set_index_list (m_index_type, m_index_list);
+    }
+
+  private:
+    tree_evaluator *m_tw;
+    const octave_value m_val;
+    const std::string m_index_type;
+    const std::list<octave_value_list> m_index_list;
+  };
+
 OCTAVE_NAMESPACE_END
 
 #endif
diff -r 9c46aea521e9 -r 1a3cd0f2e096 libinterp/parse-tree/pt-idx.cc
--- a/libinterp/parse-tree/pt-idx.cc	Tue Dec 21 22:46:12 2021 +0100
+++ b/libinterp/parse-tree/pt-idx.cc	Wed Dec 22 23:22:07 2021 +0100
@@ -376,10 +376,7 @@
 
             if (al && al->length () > 0)
               {
-                unwind_action act ([&tw] (const tiny_vector<octave_lvalue> *lvl)
-                                   {
-                                     tw.set_lvalue_list (lvl);
-                                   }, tw.lvalue_list ());
+                unwind_reset_tw_lvalue_list obj {&tw, tw.lvalue_list ()};
 
                 tw.set_lvalue_list (nullptr);
 
@@ -462,7 +459,7 @@
       // Note: need new scope so that the following unwind action will
       // happen before we perform the final indexing for objects (for
       // example).
-
+      /*
       unwind_action
         act ([&tw] (const octave_value& val,
                     const std::string& index_type,
@@ -473,6 +470,9 @@
              },
              tw.indexed_object (),
              tw.index_type (), tw.index_list ());
+*/
+      unwind_reset_tw_indexed_obj obj {&tw, tw.indexed_object (),
+                                       tw.index_type (), tw.index_list ()};
 
       tw.set_indexed_object ();
       tw.clear_index_list ();
