GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
call-stack.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1993-2024 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if ! defined (octave_call_stack_h)
27 #define octave_call_stack_h 1
28 
29 #include "octave-config.h"
30 
31 #include <deque>
32 #include <memory>
33 #include <string>
34 
35 class octave_function;
36 class octave_map;
37 class octave_user_code;
38 class octave_user_script;
39 class octave_value;
40 class octave_value_list;
41 
42 #include "quit.h"
43 
44 #include "stack-frame.h"
45 #include "symscope.h"
46 
48 
49 class tree_evaluator;
50 class symbol_info_list;
51 class unwind_protect;
52 
53 class
54 OCTINTERP_API
56 {
57 public:
58 
59  typedef std::deque<std::shared_ptr<stack_frame>> stack_frames;
60 
61  typedef stack_frames::iterator iterator;
62  typedef stack_frames::const_iterator const_iterator;
63 
64  typedef stack_frames::reverse_iterator reverse_iterator;
65  typedef stack_frames::const_reverse_iterator const_reverse_iterator;
66 
67  call_stack (tree_evaluator& evaluator);
68 
69  // Lock current function. Look for the first stack frame that is
70  // a function. If SKIP_FIST is true, then skip the first frame.
71  // That allows functions like Fmlock to find and lock the calling
72  // function instead of locking Fmlock itself.
73 
74  octave_function * current_function (bool skip_first = false) const;
75 
77  {
78  return current_function (true);
79  }
80 
81  // Current line in current function.
82  int current_line () const;
83 
84  // Current column in current function.
85  int current_column () const;
86 
87  std::size_t current_frame () const { return m_curr_frame; }
88 
89  std::size_t size () const { return m_cs.size (); }
90 
91  std::shared_ptr<stack_frame> get_current_stack_frame () const
92  {
93  return m_cs[m_curr_frame];
94  }
95 
97  {
98  return m_cs[0]->get_scope ();
99  }
100 
102  {
103  // FIXME: Can m_curr_frame ever be invalid?
104  return (m_curr_frame < m_cs.size ()
105  ? m_cs[m_curr_frame]->get_scope () : symbol_scope::invalid ());
106  }
107 
108  bool at_top_level () const
109  {
110  return current_scope () == top_scope ();
111  }
112 
113  // Function at location N on the call stack (N == 0 is current), may
114  // be built-in.
115  octave_function * element (std::size_t n)
116  {
117  octave_function *retval = nullptr;
118 
119  if (m_cs.size () > n)
120  retval = m_cs[n]->function ();
121 
122  return retval;
123  }
124 
125  // User code caller.
126  octave_user_code * current_user_code () const;
127 
128  unwind_protect * curr_fcn_unwind_protect_frame ();
129 
130  // Line in user code caller.
131  int current_user_code_line () const;
132 
133  // Column in user code caller.
134  int current_user_code_column () const;
135 
136  // Current function that we are debugging.
137  octave_user_code * debug_user_code () const;
138 
139  // Line number in current function that we are debugging.
140  int debug_user_code_line () const;
141 
142  // Column number in current function that we are debugging.
143  int debug_user_code_column () const;
144 
145  std::string get_dispatch_class () const;
146 
147  void set_dispatch_class (const std::string& class_name);
148 
149  bool is_class_method_executing (std::string& dispatch_class) const;
150 
151  bool is_class_constructor_executing (std::string& dispatch_class) const;
152 
153  // Return TRUE if all elements on the call stack are scripts.
154  bool all_scripts () const;
155 
156  void push (const symbol_scope& scope);
157 
158  void push (octave_user_function *fcn,
159  const std::shared_ptr<stack_frame>& closure_frames = std::shared_ptr<stack_frame> ());
160 
161  void push (octave_user_function *fcn,
162  const stack_frame::local_vars_map& local_vars,
163  const std::shared_ptr<stack_frame>& closure_frames = std::shared_ptr<stack_frame> ());
164 
165  void push (octave_user_script *script);
166 
167  void push (octave_function *fcn);
168 
169  void set_location (int l, int c)
170  {
171  if (! m_cs.empty ())
172  {
173  std::shared_ptr<stack_frame> elt = m_cs.back ();
174 
175  elt->line (l);
176  elt->column (c);
177  }
178  }
179 
180  void set_line (int l)
181  {
182  if (! m_cs.empty ())
183  {
184  std::shared_ptr<stack_frame> elt = m_cs.back ();
185 
186  elt->line (l);
187  }
188  }
189 
190  void set_column (int c)
191  {
192  if (! m_cs.empty ())
193  {
194  std::shared_ptr<stack_frame> elt = m_cs.back ();
195 
196  elt->column (c);
197  }
198  }
199 
200  bool goto_frame (std::size_t n = 0, bool verbose = false);
201 
202  void restore_frame (std::size_t n)
203  {
204  goto_frame (n);
205  }
206 
207  std::size_t find_current_user_frame () const;
208 
209  std::shared_ptr<stack_frame> current_user_frame () const;
210 
211  std::size_t dbupdown (std::size_t start, int n, bool verbose);
212  std::size_t dbupdown (int n = -1, bool verbose = false);
213 
214  void goto_caller_frame ();
215 
216  void goto_base_frame ();
217 
218  std::list<std::shared_ptr<stack_frame>>
219  backtrace_frames (octave_idx_type& curr_user_frame) const;
220 
221  // List of raw stack frames.
222 
223  std::list<std::shared_ptr<stack_frame>> backtrace_frames () const;
224 
225  // List of stack_info objects that can be used in liboctave and
226  // stored in the execution_exception object.
227 
228  std::list<frame_info> backtrace_info (octave_idx_type& curr_user_frame,
229  bool print_subfn = true) const;
230 
231  std::list<frame_info> backtrace_info () const;
232 
233  // The same as backtrace_info but in the form of a struct array
234  // object that may be used in the interpreter.
235 
236  octave_map backtrace (octave_idx_type& curr_user_frame,
237  bool print_subfn = true) const;
238 
239  octave_map backtrace () const;
240 
241  octave_map empty_backtrace () const;
242 
243  void pop ();
244 
245  std::shared_ptr<stack_frame> pop_return ();
246 
247  void clear ();
248 
249  symbol_info_list all_variables ();
250 
251  std::list<std::string> global_variable_names () const;
252 
253  std::list<std::string> top_level_variable_names () const;
254 
255  std::list<std::string> variable_names () const;
256 
257  void clear_global_variable (const std::string& name);
258 
259  void clear_global_variable_pattern (const std::string& pattern);
260 
261  void clear_global_variable_regexp(const std::string& pattern);
262 
263  void clear_global_variables ();
264 
265  symbol_info_list glob_symbol_info (const std::string& pattern) const;
266 
267  symbol_info_list regexp_symbol_info (const std::string& pattern) const;
268 
269  symbol_info_list get_symbol_info ();
270 
271  symbol_info_list top_scope_symbol_info () const;
272 
273  octave_value max_stack_depth (const octave_value_list& args, int nargout);
274 
275  void make_persistent (const symbol_record& sym);
276 
277  void make_global (const symbol_record& sym);
278 
279  octave_value global_varval (const std::string& name) const;
280 
281  octave_value& global_varref (const std::string& name);
282 
283  octave_value get_top_level_value (const std::string& name) const;
284 
285  void set_top_level_value (const std::string& name,
286  const octave_value& value);
287 
288  octave_value do_who (int argc, const string_vector& argv,
289  bool return_list, bool verbose = false);
290 
291  octave_value do_who_two (const string_vector& patterns, bool have_regexp,
292  bool return_list, bool verbose,
293  const std::string& msg = "");
294 
295  octave_value do_global_who_two (const string_vector& patterns,
296  bool have_regexp, bool return_list,
297  bool verbose, const std::string& msg = "");
298 
299  void display () const;
300 
301  void set_auto_fcn_var (stack_frame::auto_var_type avt,
302  const octave_value& val);
303 
304  void set_nargin (int nargin);
305  void set_nargout (int nargout);
306 
307  octave_value get_auto_fcn_var (stack_frame::auto_var_type avt) const;
308 
309 private:
310 
311  void get_new_frame_index_and_links
312  (std::size_t& new_frame_idx, std::shared_ptr<stack_frame>& parent_link,
313  std::shared_ptr<stack_frame>& static_link) const;
314 
315  tree_evaluator& m_evaluator;
316 
317  // The list of stack frames.
318  stack_frames m_cs;
319 
320  // The current frame. When a new frame is pushed, m_curr_frame
321  // moves to the end of the list of stack frames (also referred to as
322  // the top of the call stack) but may be temporarily moved to
323  // another location by evalin or debugging functions.
324 
325  // FIXME: should the current frame be managed by the evaluator
326  // instead?
327  std::size_t m_curr_frame;
328 
329  int m_max_stack_depth;
330 
331  std::map<std::string, octave_value> m_global_values;
332 };
333 
334 OCTAVE_END_NAMESPACE(octave)
335 
336 #endif
octave_function * caller_function() const
Definition: call-stack.h:76
stack_frames::const_reverse_iterator const_reverse_iterator
Definition: call-stack.h:65
void set_column(int c)
Definition: call-stack.h:190
stack_frames::iterator iterator
Definition: call-stack.h:61
std::size_t size() const
Definition: call-stack.h:89
octave_function * element(std::size_t n)
Definition: call-stack.h:115
void restore_frame(std::size_t n)
Definition: call-stack.h:202
bool at_top_level() const
Definition: call-stack.h:108
std::size_t current_frame() const
Definition: call-stack.h:87
void set_location(int l, int c)
Definition: call-stack.h:169
symbol_scope current_scope() const
Definition: call-stack.h:101
void set_line(int l)
Definition: call-stack.h:180
std::shared_ptr< stack_frame > get_current_stack_frame() const
Definition: call-stack.h:91
std::deque< std::shared_ptr< stack_frame > > stack_frames
Definition: call-stack.h:59
stack_frames::const_iterator const_iterator
Definition: call-stack.h:62
symbol_scope top_scope() const
Definition: call-stack.h:96
stack_frames::reverse_iterator reverse_iterator
Definition: call-stack.h:64
std::map< std::string, octave_value > local_vars_map
Definition: stack-frame.h:112
static symbol_scope invalid()
Definition: symscope.h:400
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
octave_idx_type n
Definition: mx-inlines.cc:761