# HG changeset patch
# User Petter Tomner <tomner@kth.se>
# Date 1641227869 -3600
#      Mon Jan 03 17:37:49 2022 +0100
# Node ID dbcc7bced1979118886488bae04609d61da4655e
# Parent  47e146d3d15da7da772f057ab4118679df01e08f
interpreter: Avoid some "nil" ovl construction and split code

libinterp/octave-value/ov-builtin.cc: Move ctor into branches

libinterp/parse-tree/
	* pt-binop.cc: Split to keep down function code size
	* pt-binop.h

diff -r 47e146d3d15d -r dbcc7bced197 libinterp/octave-value/ov-builtin.cc
--- a/libinterp/octave-value/ov-builtin.cc	Mon Jan 03 15:22:16 2022 +0100
+++ b/libinterp/octave-value/ov-builtin.cc	Mon Jan 03 17:37:49 2022 +0100
@@ -44,12 +44,11 @@
   "built-in function",
   fixed_typeid::typeid_in_function_built_in_function);
 
+
 octave_value_list
 octave_builtin::execute (octave::tree_evaluator& tw, int nargout,
                          const octave_value_list& args)
 {
-  octave_value_list retval;
-
   if (args.has_magic_colon ())
     error ("invalid use of colon in function argument list");
 
@@ -57,23 +56,12 @@
 
   octave::profiler::enter<octave_builtin> block (profiler, *this);
 
-  if (m_fcn)
-    retval = (*m_fcn) (args, nargout);
-  else
-    {
-      octave::interpreter& interp
-        = octave::__get_interpreter__ ("octave_builtin::call");
-
-      retval = (*m_meth) (interp, args, nargout);
-    }
-
-  // Do not allow null values to be returned from functions.
+  // Calling retval.make_storable_values () to
+  // not allow null values to be returned from functions.
   // FIXME: perhaps true builtins should be allowed?
 
-  retval.make_storable_values ();
-
-  // Fix the case of a single undefined value.
-  // This happens when a compiled function uses
+  // Calling retval.clear () to fix the case of a single
+  // undefined value. This happens when a compiled function uses
   //
   //   octave_value retval;
   //
@@ -83,10 +71,29 @@
   //
   // the idiom is very common, so we solve that here.
 
-  if (retval.length () == 1 && retval.xelem (0).is_undefined ())
-    retval.clear ();
+  if (m_fcn)
+    {
+      octave_value_list retval = (*m_fcn) (args, nargout);
+
+      retval.make_storable_values ();
+      if (retval.length () == 1 && retval.xelem (0).is_undefined ())
+        retval.clear ();
 
-  return retval;
+      return retval;
+    }
+  else
+    {
+      octave::interpreter& interp
+        = octave::__get_interpreter__ ("octave_builtin::call");
+
+      octave_value_list retval = (*m_meth) (interp, args, nargout);
+
+      retval.make_storable_values ();
+      if (retval.length () == 1 && retval.xelem (0).is_undefined ())
+        retval.clear ();
+
+      return retval;
+    }
 }
 
 octave_builtin::fcn
diff -r 47e146d3d15d -r dbcc7bced197 libinterp/parse-tree/pt-binop.cc
--- a/libinterp/parse-tree/pt-binop.cc	Mon Jan 03 15:22:16 2022 +0100
+++ b/libinterp/parse-tree/pt-binop.cc	Mon Jan 03 17:37:49 2022 +0100
@@ -69,51 +69,53 @@
   }
 
   octave_value
-  tree_binary_expression::evaluate (tree_evaluator& tw, int)
+  tree_binary_expression::evaluate_braindead_shortcircuit (tree_evaluator& tw)
   {
-    octave_value val;
+    if (m_lhs)
+      {
+        octave_value a = m_lhs->evaluate (tw);
 
-    if (is_eligible_for_braindead_shortcircuit ())
-      {
-        if (m_lhs)
+        if (a.ndims () == 2 && a.rows () == 1 && a.columns () == 1)
           {
-            octave_value a = m_lhs->evaluate (tw);
+            bool result = false;
 
-            if (a.ndims () == 2 && a.rows () == 1 && a.columns () == 1)
+            bool a_true = a.is_true ();
+
+            if (a_true)
               {
-                bool result = false;
-
-                bool a_true = a.is_true ();
-
-                if (a_true)
+                if (m_etype == octave_value::op_el_or)
                   {
-                    if (m_etype == octave_value::op_el_or)
-                      {
-                        matlab_style_short_circuit_warning ("|");
-                        return octave_value (true);
-                      }
+                    matlab_style_short_circuit_warning ("|");
+                    return octave_value (true);
                   }
-                else
+              }
+            else
+              {
+                if (m_etype == octave_value::op_el_and)
                   {
-                    if (m_etype == octave_value::op_el_and)
-                      {
-                        matlab_style_short_circuit_warning ("&");
-                        return octave_value (false);
-                      }
+                    matlab_style_short_circuit_warning ("&");
+                    return octave_value (false);
                   }
+              }
 
-                if (m_rhs)
-                  {
-                    octave_value b = m_rhs->evaluate (tw);
+            if (m_rhs)
+              {
+                octave_value b = m_rhs->evaluate (tw);
 
-                    result = b.is_true ();
-                  }
+                result = b.is_true ();
+              }
 
-                return octave_value (result);
-              }
+            return octave_value (result);
           }
       }
 
+    // Do normal
+    return evaluate_normal (tw);
+  }
+
+  octave_value
+  tree_binary_expression::evaluate_normal (tree_evaluator& tw)
+  {
     if (m_lhs)
       {
         octave_value a = m_lhs->evaluate (tw);
@@ -128,7 +130,7 @@
                   block (tw.get_profiler (), *this);
 
                 // Note: The profiler does not catch the braindead
-                // short-circuit evaluation code above, but that should be
+                // short-circuit evaluation code, but that should be
                 // ok.  The evaluation of operands and the operator itself
                 // is entangled and it's not clear where to start/stop
                 // timing the operator to make it reasonable.
@@ -137,12 +139,21 @@
 
                 type_info& ti = interp.get_type_info ();
 
-                val = binary_op (ti, m_etype, a, b);
+                return  binary_op (ti, m_etype, a, b);
               }
           }
       }
 
-    return val;
+    return octave_value ();
+  }
+
+  octave_value
+  tree_binary_expression::evaluate (tree_evaluator& tw, int)
+  {
+    if (is_eligible_for_braindead_shortcircuit ())
+      return evaluate_braindead_shortcircuit(tw);
+
+    return evaluate_normal(tw);
   }
 
   // Boolean expressions.
diff -r 47e146d3d15d -r dbcc7bced197 libinterp/parse-tree/pt-binop.h
--- a/libinterp/parse-tree/pt-binop.h	Mon Jan 03 15:22:16 2022 +0100
+++ b/libinterp/parse-tree/pt-binop.h	Mon Jan 03 17:37:49 2022 +0100
@@ -127,6 +127,9 @@
     tree_expression *m_rhs;
 
   private:
+    // Internal helper functions
+    octave_value evaluate_braindead_shortcircuit (tree_evaluator&);
+    octave_value evaluate_normal (tree_evaluator&);
 
     // The type of the expression.
     octave_value::binary_op m_etype;
