Mercurial > octave
changeset 32141:e1aacfd46471
new value class to manage references to octave_value objects
* ov-ref.h, ov-ref.cc: New files.
* libinterp/octave-value/module.mk: Update.
* ov-base.h, ov-base.cc (octave_base_value::is_ref,
octave_base_value::ref_rep): New virtual functions.
* ov.h (octave_value::is_ref, octave_value::ref_rep): New functions.
author | Petter T. <petter.vilhelm@gmail.com> |
---|---|
date | Mon, 19 Jun 2023 13:13:03 -0400 |
parents | 8877fb5301b6 |
children | 53ba75432f02 |
files | libinterp/octave-value/module.mk libinterp/octave-value/ov-base.cc libinterp/octave-value/ov-base.h libinterp/octave-value/ov-ref.cc libinterp/octave-value/ov-ref.h libinterp/octave-value/ov.h |
diffstat | 6 files changed, 261 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/octave-value/module.mk Mon Jun 19 12:01:24 2023 -0400 +++ b/libinterp/octave-value/module.mk Mon Jun 19 13:13:03 2023 -0400 @@ -62,6 +62,7 @@ %reldir%/ov-perm.h \ %reldir%/ov-range-traits.h \ %reldir%/ov-range.h \ + %reldir%/ov-ref.h \ %reldir%/ov-re-diag.h \ %reldir%/ov-re-mat.h \ %reldir%/ov-scalar.h \ @@ -128,6 +129,7 @@ %reldir%/ov-oncleanup.cc \ %reldir%/ov-perm.cc \ %reldir%/ov-range.cc \ + %reldir%/ov-ref.cc \ %reldir%/ov-re-diag.cc \ %reldir%/ov-re-mat.cc \ %reldir%/ov-scalar.cc \
--- a/libinterp/octave-value/ov-base.cc Mon Jun 19 12:01:24 2023 -0400 +++ b/libinterp/octave-value/ov-base.cc Mon Jun 19 13:13:03 2023 -0400 @@ -950,6 +950,14 @@ return nullptr; } +octave_value_ref * +octave_base_value::ref_rep () +{ + err_wrong_type_arg ("octave_base_value::ref_value()", type_name ()); + + return nullptr; +} + octave_user_function * octave_base_value::user_function_value (bool silent) {
--- a/libinterp/octave-value/ov-base.h Mon Jun 19 12:01:24 2023 -0400 +++ b/libinterp/octave-value/ov-base.h Mon Jun 19 13:13:03 2023 -0400 @@ -805,6 +805,10 @@ virtual octave_base_value * make_storable_value (void); + virtual bool is_ref () const { return false; } + + virtual octave_value_ref * ref_rep (); + virtual bool maybe_update_double (double d); virtual bool is_trivial_range () const { return false; };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/octave-value/ov-ref.cc Mon Jun 19 13:13:03 2023 -0400 @@ -0,0 +1,123 @@ +//////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2007-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 (HAVE_CONFIG_H) +# include "config.h" +#endif + +#include "ov.h" +#include "ov-ref.h" + + +#include "interpreter.h" +#include "interpreter-private.h" + +DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_value_ref_global, + "global value reference", + "global value reference"); +DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_value_ref_persistent, + "global value persistent", + "global value persistent"); +void +octave_value_ref::maybe_call_dtor () +{ + ref ().m_rep->maybe_call_dtor (); +} + +bool +octave_value_ref::is_defined () const +{ + return const_cast<octave_value_ref*> (this)->ref ().m_rep->is_defined (); +} + +bool +octave_value_ref::is_maybe_function () const +{ + return const_cast<octave_value_ref*> (this)->ref ().m_rep->is_maybe_function (); +} + +octave_base_value * +octave_value_ref::unique_clone () +{ + return ref ().m_rep->unique_clone (); +} + +octave_value +octave_value_ref::simple_subsasgn (char type, octave_value_list& idx, const octave_value& rhs) +{ + octave_value ans = ref ().m_rep->simple_subsasgn (type, idx, rhs); + ref () = ans; + return octave_value {this, true}; +} + +octave_value +octave_value_ref::subsasgn (const std::string& type, + const std::list<octave_value_list>& idx, + const octave_value& rhs) +{ + octave_value ans = ref ().m_rep->subsasgn (type, idx, rhs); + ref () = ans; + return octave_value {this, true}; +} + +octave_value +octave_value_ref_global::deref () +{ + auto &interp = octave::__get_interpreter__(); + return interp.global_varval (m_name); +} + +void +octave_value_ref_global::set_value (octave_value val) +{ + auto &interp = octave::__get_interpreter__(); + interp.global_assign (m_name, val); +} + +octave_value& +octave_value_ref_global::ref () +{ + auto& tw = octave::__get_evaluator__(); + return tw.global_varref (m_name); +} + +octave_value +octave_value_ref_persistent::deref () +{ + return m_scope.persistent_varval (m_offset); +} + +void +octave_value_ref_persistent::set_value (octave_value val) +{ + octave_value &ov_pers = m_scope.persistent_varref (m_offset); + ov_pers = val; +} + +octave_value & +octave_value_ref_persistent::ref () +{ + return m_scope.persistent_varref (m_offset); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/octave-value/ov-ref.h Mon Jun 19 13:13:03 2023 -0400 @@ -0,0 +1,117 @@ +//////////////////////////////////////////////////////////////////////// +// +// 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_ref_h) +#define octave_ov_ref_h 1 + +#include "octave-config.h" + +#include "ov-base.h" +#include "ovl.h" +#include "symscope.h" + +#include <string> +#include <memory> + +// octave_value_ref is to be used by the VM to implement +// global and persistent values. +// +// octave_value_ref need to overload any virtual call +// used by the assign and push slot op-codes. +// +// Any octave_value_ref should never leave the VM slots +// on the VM stack. + +// Abstract type +class OCTINTERP_API +octave_value_ref : public octave_base_value +{ +public: + octave_value_ref () = default; + ~octave_value_ref () = default; + + octave_value_ref * ref_rep () { return this; } + bool is_ref () const { return true; } + + virtual octave_value deref () = 0; + virtual void set_value (octave_value val) = 0; + virtual octave_value & ref () = 0; + virtual void maybe_save_state () {}; + + virtual bool is_global_ref () { return false; } + virtual bool is_persistent_ref () { return false; } + + void maybe_call_dtor (); + octave_value simple_subsasgn (char type, octave_value_list& idx, const octave_value& rhs); + octave_value subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs); + octave_base_value * unique_clone (); + bool is_defined () const; + bool is_maybe_function (void) const; +}; + +class OCTINTERP_API +octave_value_ref_global : public octave_value_ref +{ +public: + octave_value_ref_global () = default; + ~octave_value_ref_global () = default; + octave_value_ref_global (std::string name) + : m_name (name) {}; + + octave_value deref (); + octave_value & ref (); + void set_value (octave_value val); + + bool is_global_ref () { return true; } + +private: + std::string m_name; + + DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA +}; + +class OCTINTERP_API +octave_value_ref_persistent : public octave_value_ref +{ +public: + octave_value_ref_persistent () = default; + ~octave_value_ref_persistent () = default; + octave_value_ref_persistent (octave::symbol_scope scope, int offset) + : m_offset (offset), m_scope (scope) {}; + + octave_value deref (); + octave_value & ref (); + void set_value (octave_value val); + + bool is_persistent_ref () { return true; } + +private: + int m_offset; + octave::symbol_scope m_scope; + + DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA +}; + +#endif
--- a/libinterp/octave-value/ov.h Mon Jun 19 12:01:24 2023 -0400 +++ b/libinterp/octave-value/ov.h Mon Jun 19 13:13:03 2023 -0400 @@ -1535,6 +1535,13 @@ protected: + // Functions for use by the VM. + friend class octave_value_ref; + + bool is_ref () const { return m_rep->is_ref (); } + + octave_value_ref * ref_rep () { return m_rep->ref_rep (); } + // True for the types based on ov-base-mat bool is_full_num_matrix () const { return m_rep->is_full_num_matrix (); }