changeset 32144:a36ba266f4eb

new octave_value class that disallows self-assignment * ov-vm.h: New file. * libinterp/octave-value/module.mk: Update. * ov.h (class octave_value): Declare octave_value_vm as friend class. * ov-base.h (class octave_base_value): Declare octave_value_vm as friend class.
author Petter T. <petter.vilhelm@gmail.com>
date Mon, 19 Jun 2023 14:16:39 -0400
parents 9af044b8e228
children 00740c1f8e82
files libinterp/octave-value/module.mk libinterp/octave-value/ov-base.h libinterp/octave-value/ov-vm.h libinterp/octave-value/ov.h
diffstat 4 files changed, 172 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/octave-value/module.mk	Mon Jun 19 14:14:26 2023 -0400
+++ b/libinterp/octave-value/module.mk	Mon Jun 19 14:16:39 2023 -0400
@@ -71,6 +71,7 @@
   %reldir%/ov-typeinfo.h \
   %reldir%/ov-usr-fcn.h \
   %reldir%/ov.h \
+  %reldir%/ov-vm.h \
   %reldir%/ovl.h \
   $(OV_INTTYPE_INC) \
   $(OV_SPARSE_INC)
--- a/libinterp/octave-value/ov-base.h	Mon Jun 19 14:14:26 2023 -0400
+++ b/libinterp/octave-value/ov-base.h	Mon Jun 19 14:16:39 2023 -0400
@@ -80,6 +80,7 @@
 class octave_value_list;
 class octave_value_ref;
 class octave_fcn_cache;
+class octave_value_vm;
 
 enum builtin_type_t
 {
@@ -263,6 +264,7 @@
   };
 
   friend class octave_value;
+  friend class octave_value_vm;
 
   octave_base_value ();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/octave-value/ov-vm.h	Mon Jun 19 14:16:39 2023 -0400
@@ -0,0 +1,168 @@
+////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 1996-2023 The Octave Project Developers
+//
+// See the file COPYRIGHT.md in the top-level directory of this
+// distribution or <https://octave.org/copyright/>.
+//
+// This file is part of Octave.
+//
+// Octave is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Octave is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Octave; see the file COPYING.  If not, see
+// <https://www.gnu.org/licenses/>.
+//
+////////////////////////////////////////////////////////////////////////
+
+#if ! defined (octave_ov_vm_h)
+#define octave_ov_vm_h 1
+
+#include "octave-config.h"
+
+#include "ov.h"
+
+
+// octave_value_vm is to be used only by the VM
+// and need to have the same bit representation as
+// an octave_value.
+//
+// A octave_value_vm object might not be assigned 
+// to itself or have a nullptr m_rep when being
+// assigned to.
+
+class octave_value_vm
+{
+public:
+  octave_value_vm ()
+      : m_rep (octave_value::nil_rep ())
+  {
+      m_rep->m_count++;
+  }
+
+  octave_value_vm (octave_base_value *rep, bool count_add1 = true)
+    : m_rep (rep)
+  {
+    if (count_add1)
+      m_rep->m_count++;
+  }
+
+  octave_value_vm (const octave_value_vm& a)
+      : m_rep (a.m_rep)
+  {
+      m_rep->m_count++;
+  }
+  octave_value_vm (const octave_value& a)
+      : m_rep (a.m_rep)
+  {
+      m_rep->m_count++;
+  }
+
+  octave_value_vm (octave_value_vm&& a)
+  : m_rep (a.m_rep)
+  {
+      a.m_rep = nullptr;
+  }
+  octave_value_vm (octave_value&& a)
+  : m_rep (a.m_rep)
+  {
+      a.m_rep = nullptr;
+  }
+
+  ~octave_value_vm () __attribute__ ((always_inline))
+  {
+      // Because we define a move constructor and a move assignment
+      // operator, rep may be a nullptr here.  We should only need to
+      // protect the move assignment operator in a similar way.
+
+    if (m_rep && --m_rep->m_count == 0)
+      delete m_rep;
+  }
+
+  octave_value_vm& operator = (const octave_value_vm& a)
+  {
+    if (--m_rep->m_count == 0)
+      delete m_rep;
+
+    m_rep = a.m_rep;
+    m_rep->m_count++;
+
+    return *this;
+  }
+
+  octave_value_vm& operator = (octave_value_vm&& a)
+  {
+    if (--m_rep->m_count == 0)
+      delete m_rep;
+
+    m_rep = a.m_rep;
+    a.m_rep = nullptr;
+
+    return *this;
+  }
+
+  octave_value_vm& operator = (octave_value&& a)
+  {
+    if (--m_rep->m_count == 0)
+      delete m_rep;
+
+    m_rep = a.m_rep;
+    a.m_rep = nullptr;
+
+    return *this;
+  }
+
+  static void release_rep (octave_base_value *rep)
+  {
+    if (--rep->m_count == 0)
+      delete rep;
+  }
+
+  void steal_ov_rep (octave_value &&ov)
+  {
+    if (m_rep && --m_rep->m_count == 0)
+      delete m_rep;
+
+    m_rep = ov.m_rep;
+    ov.m_rep = nullptr;
+  }
+
+  octave_base_value & get_rep () { return *m_rep; }
+
+  octave_value_vm& operator = (octave_base_value *rep)
+  {
+    if (--m_rep->m_count == 0)
+      delete m_rep;
+
+    m_rep = rep;
+
+    return *this;
+  }
+
+  bool vm_need_dispatch_push () __attribute__ ((pure, always_inline, nothrow))
+  { return m_rep->vm_need_dispatch_push (); }
+
+  bool vm_need_dispatch_assign_rhs () __attribute__ ((pure, always_inline, nothrow))
+  { return m_rep->vm_need_dispatch_assign_rhs (); }
+
+  bool vm_need_dispatch_assign_lhs () __attribute__ ((pure, always_inline, nothrow))
+  { return m_rep->vm_need_dispatch_assign_lhs (); }
+
+  int type_id() const __attribute__ ((pure, always_inline, nothrow))
+  { return m_rep->type_id (); }
+
+  bool is_matrix_type () const __attribute__ ((pure, always_inline, nothrow))
+  { return m_rep->is_matrix_type (); }
+
+  octave_base_value *m_rep;
+};
+
+#endif
--- a/libinterp/octave-value/ov.h	Mon Jun 19 14:14:26 2023 -0400
+++ b/libinterp/octave-value/ov.h	Mon Jun 19 14:16:39 2023 -0400
@@ -1537,6 +1537,7 @@
 
   // Functions for use by the VM.
   friend class octave_value_ref;
+  friend class octave_value_vm;
 
   bool is_ref () const { return m_rep->is_ref (); }