Mercurial > octave
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