# HG changeset patch # User Jaroslav Hajek # Date 1245931058 -7200 # Node ID 17af7cce7d1bb1dcd5a7eafe0ec0e9e5251184f0 # Parent 1de00ca9c9f242af6be6611fc7c1ee046627715f yet more unwind_protect improvements diff -r 1de00ca9c9f2 -r 17af7cce7d1b src/ChangeLog --- a/src/ChangeLog Thu Jun 25 11:41:46 2009 +0200 +++ b/src/ChangeLog Thu Jun 25 13:57:38 2009 +0200 @@ -1,3 +1,29 @@ +2009-06-25 Jaroslav Hajek + + * unwind-prot.h (unwind_protect::fcn_elem): New class. + (unwind_protect::fcn_arg_elem): New class. + (unwind_protect::method_elem): New class. + (unwind_protect::add_action_var): Rename to add_fcn. + (unwind_protect::add_fcn): New static method. + (unwind_protect::add_method): New static method. + + * symtab.h: Split clear_variables into two overloads. + * toplev.h (octave_call_stack::restore_frame): New static method. + + * graphics.cc: Update unwind_protect usage. + * input.cc: Ditto. + * lex.h: Ditto. + * ls-mat5.cc: Ditto. + * mex.cc: Ditto. + * ov-builtin.cc: Ditto. + * ov-fcn-handle.cc: Ditto. + * ov-mex-fcn.cc: Ditto. + * ov-usr-fcn.cc: Ditto. + * parse.y: Ditto. + * pt-eval.cc: Ditto. + * toplev.cc: Ditto. + * variables.cc: Ditto. + 2009-06-25 Jaroslav Hajek * input.cc: Use unwind_protect::add_action_var where appropriate. diff -r 1de00ca9c9f2 -r 17af7cce7d1b src/graphics.cc --- a/src/graphics.cc Thu Jun 25 11:41:46 2009 +0200 +++ b/src/graphics.cc Thu Jun 25 13:57:38 2009 +0200 @@ -4190,7 +4190,7 @@ args(1) = Matrix (); unwind_protect::frame_id_t uwp_frame = unwind_protect::begin_frame (); - unwind_protect::add (gh_manager::restore_gcbo); + unwind_protect::add_fcn (gh_manager::restore_gcbo); if (true) { @@ -4989,12 +4989,6 @@ return octave_value (graphics_backend::available_backends_list ()); } -static void -clear_drawnow_request (void *) -{ - Vdrawnow_requested = false; -} - DEFUN (drawnow, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} drawnow ()\n\ @@ -5016,7 +5010,7 @@ gh_manager::lock (); unwind_protect::frame_id_t uwp_frame = unwind_protect::begin_frame (); - unwind_protect::add (clear_drawnow_request); + unwind_protect::protect_var (Vdrawnow_requested, false); unwind_protect::protect_var (drawnow_executing); diff -r 1de00ca9c9f2 -r 17af7cce7d1b src/input.cc --- a/src/input.cc Thu Jun 25 11:41:46 2009 +0200 +++ b/src/input.cc Thu Jun 25 13:57:38 2009 +0200 @@ -669,7 +669,7 @@ // Do this with an unwind-protect cleanup function so that the // forced variables will be unmarked in the event of an interrupt. symbol_table::scope_id scope = symbol_table::top_scope (); - unwind_protect::add_action_var (symbol_table::unmark_forced_variables, scope); + unwind_protect::add_fcn (symbol_table::unmark_forced_variables, scope); // This is the same as yyparse in parse.y. int retval = octave_parse (); @@ -874,20 +874,6 @@ return retval; } -static void -restore_command_history (void *) -{ - command_history::ignore_entries (! Vsaving_history); -} - -static size_t saved_frame = 0; - -static void -restore_frame (void *) -{ - octave_call_stack::goto_frame (saved_frame); -} - octave_value do_keyboard (const octave_value_list& args) { @@ -904,14 +890,13 @@ // Vsaving_history variable... command_history::ignore_entries (false); - unwind_protect::add (restore_command_history, 0); + unwind_protect::add_fcn (command_history::ignore_entries, ! Vsaving_history); unwind_protect::protect_var (Vsaving_history); unwind_protect::protect_var (Vdebugging); - saved_frame = octave_call_stack::current_frame (); - unwind_protect::add (restore_frame); - unwind_protect::protect_var (saved_frame); + unwind_protect::add_fcn (octave_call_stack::restore_frame, + octave_call_stack::current_frame ()); Vsaving_history = true; Vdebugging = true; @@ -951,9 +936,8 @@ if (nargin == 0 || nargin == 1) { - saved_frame = octave_call_stack::current_frame (); - unwind_protect::add (restore_frame); - unwind_protect::protect_var (saved_frame); + unwind_protect::add_fcn (octave_call_stack::restore_frame, + octave_call_stack::current_frame ()); // Skip the frame assigned to the keyboard function. octave_call_stack::goto_frame (1); diff -r 1de00ca9c9f2 -r 17af7cce7d1b src/lex.h --- a/src/lex.h Thu Jun 25 11:41:46 2009 +0200 +++ b/src/lex.h Thu Jun 25 13:57:38 2009 +0200 @@ -43,12 +43,6 @@ // Delete a buffer. extern OCTINTERP_API void delete_buffer (YY_BUFFER_STATE buf); -// Restore a buffer (for unwind-prot). -extern OCTINTERP_API void restore_input_buffer (void *buf); - -// Delete a buffer (for unwind-prot). -extern OCTINTERP_API void delete_input_buffer (void *buf); - // Is the given string a keyword? extern bool is_keyword (const std::string& s); diff -r 1de00ca9c9f2 -r 17af7cce7d1b src/ls-mat5.cc --- a/src/ls-mat5.cc Thu Jun 25 11:41:46 2009 +0200 +++ b/src/ls-mat5.cc Thu Jun 25 13:57:38 2009 +0200 @@ -875,12 +875,12 @@ // that defines the anonymous function. symbol_table::scope_id local_scope = symbol_table::alloc_scope (); - unwind_protect::add_action_var (symbol_table::erase_scope, local_scope); + unwind_protect::add_fcn (symbol_table::erase_scope, local_scope); symbol_table::set_scope (local_scope); octave_call_stack::push (local_scope, 0); - unwind_protect::add (octave_call_stack::unwind_pop, 0); + unwind_protect::add_fcn (octave_call_stack::pop); if (m2.nfields() > 0) { diff -r 1de00ca9c9f2 -r 17af7cce7d1b src/mex.cc --- a/src/mex.cc Thu Jun 25 11:41:46 2009 +0200 +++ b/src/mex.cc Thu Jun 25 13:57:38 2009 +0200 @@ -3283,7 +3283,7 @@ octave_call_stack::goto_base_frame (); if (! error_state) - unwind_protect::add (octave_call_stack::unwind_pop); + unwind_protect::add_fcn (octave_call_stack::pop); val = symbol_table::varval (name); } @@ -3343,7 +3343,7 @@ octave_call_stack::goto_base_frame (); if (! error_state) - unwind_protect::add (octave_call_stack::unwind_pop); + unwind_protect::add_fcn (octave_call_stack::pop); symbol_table::varref (name) = mxArray::as_octave_value (ptr); } diff -r 1de00ca9c9f2 -r 17af7cce7d1b src/ov-builtin.cc --- a/src/ov-builtin.cc Thu Jun 25 11:41:46 2009 +0200 +++ b/src/ov-builtin.cc Thu Jun 25 13:57:38 2009 +0200 @@ -100,7 +100,7 @@ octave_call_stack::push (this); - unwind_protect::add (octave_call_stack::unwind_pop, 0); + unwind_protect::add_fcn (octave_call_stack::pop); try { diff -r 1de00ca9c9f2 -r 17af7cce7d1b src/ov-fcn-handle.cc --- a/src/ov-fcn-handle.cc Thu Jun 25 11:41:46 2009 +0200 +++ b/src/ov-fcn-handle.cc Thu Jun 25 13:57:38 2009 +0200 @@ -319,12 +319,12 @@ // defines the anonymous function. symbol_table::scope_id local_scope = symbol_table::alloc_scope (); - unwind_protect::add_action_var (symbol_table::erase_scope, local_scope); + unwind_protect::add_fcn (symbol_table::erase_scope, local_scope); symbol_table::set_scope (local_scope); octave_call_stack::push (local_scope, 0); - unwind_protect::add (octave_call_stack::unwind_pop, 0); + unwind_protect::add_fcn (octave_call_stack::pop); octave_idx_type len = 0; @@ -500,12 +500,12 @@ // defines the anonymous function. symbol_table::scope_id local_scope = symbol_table::alloc_scope (); - unwind_protect::add_action_var (symbol_table::erase_scope, local_scope); + unwind_protect::add_fcn (symbol_table::erase_scope, local_scope); symbol_table::set_scope (local_scope); octave_call_stack::push (local_scope, 0); - unwind_protect::add (octave_call_stack::unwind_pop, 0); + unwind_protect::add_fcn (octave_call_stack::pop); if (len > 0) { @@ -945,12 +945,12 @@ // defines the anonymous function. symbol_table::scope_id local_scope = symbol_table::alloc_scope (); - unwind_protect::add_action_var (symbol_table::erase_scope, local_scope); + unwind_protect::add_fcn (symbol_table::erase_scope, local_scope); symbol_table::set_scope (local_scope); octave_call_stack::push (local_scope, 0); - unwind_protect::add (octave_call_stack::unwind_pop, 0); + unwind_protect::add_fcn (octave_call_stack::pop); if (len > 0 && success) { diff -r 1de00ca9c9f2 -r 17af7cce7d1b src/ov-mex-fcn.cc --- a/src/ov-mex-fcn.cc Thu Jun 25 11:41:46 2009 +0200 +++ b/src/ov-mex-fcn.cc Thu Jun 25 13:57:38 2009 +0200 @@ -143,7 +143,7 @@ octave_call_stack::push (this); - unwind_protect::add (octave_call_stack::unwind_pop, 0); + unwind_protect::add_fcn (octave_call_stack::pop); try { diff -r 1de00ca9c9f2 -r 17af7cce7d1b src/ov-usr-fcn.cc --- a/src/ov-usr-fcn.cc Thu Jun 25 11:41:46 2009 +0200 +++ b/src/ov-usr-fcn.cc Thu Jun 25 13:57:38 2009 +0200 @@ -126,7 +126,7 @@ { octave_call_stack::push (this); - unwind_protect::add (octave_call_stack::unwind_pop, 0); + unwind_protect::add_fcn (octave_call_stack::pop); unwind_protect::protect_var (tree_evaluator::in_fcn_or_script_body); tree_evaluator::in_fcn_or_script_body = true; @@ -275,24 +275,6 @@ return retval; } -static void -clear_param_list (void *lst) -{ - tree_parameter_list *tmp = static_cast (lst); - - if (tmp) - tmp->undefine (); -} - -static void -restore_args_passed (void *fcn) -{ - octave_user_function *tmp = static_cast (fcn); - - if (tmp) - tmp->restore_args_passed (); -} - octave_value_list octave_user_function::subsref (const std::string& type, const std::list& idx, @@ -362,20 +344,20 @@ // eval_undefined_error(). octave_call_stack::push (this, local_scope, call_depth); - unwind_protect::add (octave_call_stack::unwind_pop, 0); + unwind_protect::add_fcn (octave_call_stack::pop); if (call_depth > 0) { symbol_table::push_context (); - unwind_protect::add (symbol_table::pop_context); + unwind_protect::add_fcn (symbol_table::pop_context); } // Save and restore args passed for recursive calls. save_args_passed (args); - unwind_protect::add (::restore_args_passed, this); + unwind_protect::add_method (this, &octave_user_function::restore_args_passed); string_vector arg_names = args.name_tags (); @@ -393,13 +375,17 @@ // Doing so decrements the reference counts on the values of local // variables that are also named function parameters. - unwind_protect::add (clear_param_list, param_list); + if (param_list) + unwind_protect::add_method (param_list, + &tree_parameter_list::undefine); // Force return list to be undefined when this function exits. // Doing so decrements the reference counts on the values of local // variables that are also named values returned by this function. - unwind_protect::add (clear_param_list, ret_list); + if (ret_list) + unwind_protect::add_method (ret_list, + &tree_parameter_list::undefine); if (call_depth == 0) { @@ -413,7 +399,7 @@ // declared global will be unmarked as global before they are // undefined by the clear_param_list cleanup function. - unwind_protect::add (symbol_table::clear_variables); + unwind_protect::add_fcn (symbol_table::clear_variables); } // The following code is in a separate scope to avoid warnings from diff -r 1de00ca9c9f2 -r 17af7cce7d1b src/parse.y --- a/src/parse.y Thu Jun 25 11:41:46 2009 +0200 +++ b/src/parse.y Thu Jun 25 13:57:38 2009 +0200 @@ -1547,13 +1547,13 @@ { tree_expression *retval = e; - unwind_protect::begin_frame ("fold_binary_expression"); - - unwind_protect_int (error_state); - unwind_protect_int (warning_state); - - unwind_protect_bool (discard_error_messages); - unwind_protect_bool (discard_warning_messages); + unwind_protect::frame_id_t uwp_frame = unwind_protect::begin_frame (); + + unwind_protect::protect_var (error_state); + unwind_protect::protect_var (warning_state); + + unwind_protect::protect_var (discard_error_messages); + unwind_protect::protect_var (discard_warning_messages); discard_error_messages = true; discard_warning_messages = true; @@ -1590,7 +1590,7 @@ } } - unwind_protect::run_frame ("fold_binary_expression"); + unwind_protect::run_frame (uwp_frame); return retval; } @@ -1600,13 +1600,13 @@ { tree_expression *retval = e; - unwind_protect::begin_frame ("fold_unary_expression"); - - unwind_protect_int (error_state); - unwind_protect_int (warning_state); - - unwind_protect_bool (discard_error_messages); - unwind_protect_bool (discard_warning_messages); + unwind_protect::frame_id_t uwp_frame = unwind_protect::begin_frame (); + + unwind_protect::protect_var (error_state); + unwind_protect::protect_var (warning_state); + + unwind_protect::protect_var (discard_error_messages); + unwind_protect::protect_var (discard_warning_messages); discard_error_messages = true; discard_warning_messages = true; @@ -1636,7 +1636,7 @@ } } - unwind_protect::run_frame ("fold_unary_expression"); + unwind_protect::run_frame (uwp_frame); return retval; } @@ -1648,13 +1648,13 @@ { tree_expression *retval = e; - unwind_protect::begin_frame ("finish_colon_expression"); - - unwind_protect_int (error_state); - unwind_protect_int (warning_state); - - unwind_protect_bool (discard_error_messages); - unwind_protect_bool (discard_warning_messages); + unwind_protect::frame_id_t uwp_frame = unwind_protect::begin_frame (); + + unwind_protect::protect_var (error_state); + unwind_protect::protect_var (warning_state); + + unwind_protect::protect_var (discard_error_messages); + unwind_protect::protect_var (discard_warning_messages); discard_error_messages = true; discard_warning_messages = true; @@ -1702,7 +1702,7 @@ } } - unwind_protect::run_frame ("finish_colon_expression"); + unwind_protect::run_frame (uwp_frame); return retval; } @@ -2859,13 +2859,13 @@ { tree_expression *retval = m; - unwind_protect::begin_frame ("finish_matrix"); - - unwind_protect_int (error_state); - unwind_protect_int (warning_state); - - unwind_protect_bool (discard_error_messages); - unwind_protect_bool (discard_warning_messages); + unwind_protect::frame_id_t uwp_frame = unwind_protect::begin_frame (); + + unwind_protect::protect_var (error_state); + unwind_protect::protect_var (warning_state); + + unwind_protect::protect_var (discard_error_messages); + unwind_protect::protect_var (discard_warning_messages); discard_error_messages = true; discard_warning_messages = true; @@ -2893,7 +2893,7 @@ } } - unwind_protect::run_frame ("finish_matrix"); + unwind_protect::run_frame (uwp_frame); return retval; } @@ -3139,24 +3139,12 @@ return status; } -static void -restore_command_history (void *) -{ - command_history::ignore_entries (! Vsaving_history); -} - -static void -restore_input_stream (void *f) -{ - command_editor::set_input_stream (static_cast (f)); -} - static octave_function * parse_fcn_file (const std::string& ff, const std::string& dispatch_type, bool force_script = false, bool require_file = true, const std::string& warn_for = std::string ()) { - unwind_protect::begin_frame ("parse_fcn_file"); + unwind_protect::frame_id_t uwp_frame = unwind_protect::begin_frame (); octave_function *fcn_ptr = 0; @@ -3166,17 +3154,18 @@ FILE *in_stream = command_editor::get_input_stream (); - unwind_protect::add (restore_input_stream, in_stream); - - unwind_protect_ptr (ff_instream); - - unwind_protect_int (input_line_number); - unwind_protect_int (current_input_column); - unwind_protect_int (end_tokens_expected); - unwind_protect_bool (reading_fcn_file); - unwind_protect_bool (line_editing); - unwind_protect_str (parent_function_name); - unwind_protect_str (current_class_name); + unwind_protect::add_fcn (command_editor::set_input_stream, + in_stream); + + unwind_protect::protect_var (ff_instream); + + unwind_protect::protect_var (input_line_number); + unwind_protect::protect_var (current_input_column); + unwind_protect::protect_var (end_tokens_expected); + unwind_protect::protect_var (reading_fcn_file); + unwind_protect::protect_var (line_editing); + unwind_protect::protect_var (parent_function_name); + unwind_protect::protect_var (current_class_name); input_line_number = 1; current_input_column = 1; @@ -3187,14 +3176,14 @@ current_class_name = dispatch_type; // The next four lines must be in this order. - unwind_protect::add (restore_command_history, 0); + unwind_protect::add_fcn (command_history::ignore_entries, ! Vsaving_history); // FIXME -- we shouldn't need both the // command_history object and the // Vsaving_history variable... command_history::ignore_entries (); - unwind_protect_bool (Vsaving_history); + unwind_protect::protect_var (Vsaving_history); Vsaving_history = false; @@ -3214,8 +3203,8 @@ bool parsing_script = false; - unwind_protect_bool (get_input_from_eval_string); - unwind_protect_bool (parser_end_of_input); + unwind_protect::protect_var (get_input_from_eval_string); + unwind_protect::protect_var (parser_end_of_input); get_input_from_eval_string = false; parser_end_of_input = false; @@ -3224,8 +3213,8 @@ { file_type = "function"; - unwind_protect_int (Vecho_executing_commands); - unwind_protect_bool (reading_fcn_file); + unwind_protect::protect_var (Vecho_executing_commands); + unwind_protect::protect_var (reading_fcn_file); Vecho_executing_commands = ECHO_OFF; reading_fcn_file = true; @@ -3238,7 +3227,7 @@ // proper value when we unwind from this frame. reading_fcn_file = old_reading_fcn_file_state; - unwind_protect_bool (reading_script_file); + unwind_protect::protect_var (reading_script_file); reading_script_file = true; @@ -3248,12 +3237,12 @@ YY_BUFFER_STATE old_buf = current_buffer (); YY_BUFFER_STATE new_buf = create_buffer (ffile); - unwind_protect::add (restore_input_buffer, old_buf); - unwind_protect::add (delete_input_buffer, new_buf); + unwind_protect::add_fcn (switch_to_buffer, old_buf); + unwind_protect::add_fcn (delete_buffer, new_buf); switch_to_buffer (new_buf); - unwind_protect_ptr (curr_fcn_ptr); + unwind_protect::protect_var (curr_fcn_ptr); curr_fcn_ptr = 0; reset_parser (); @@ -3262,7 +3251,7 @@ // the forced variables will be unmarked in the event of an // interrupt. symbol_table::scope_id scope = symbol_table::top_scope (); - unwind_protect::add_action_var (symbol_table::unmark_forced_variables, scope); + unwind_protect::add_fcn (symbol_table::unmark_forced_variables, scope); if (! help_txt.empty ()) help_buf.push (help_txt); @@ -3286,7 +3275,7 @@ else if (! warn_for.empty ()) error ("%s: unable to open file `%s'", warn_for.c_str (), ff.c_str ()); - unwind_protect::run_frame ("parse_fcn_file"); + unwind_protect::run_frame (uwp_frame); return fcn_ptr; } @@ -3386,7 +3375,7 @@ { octave_function *retval = 0; - unwind_protect::begin_frame ("load_fcn_from_file"); + unwind_protect::frame_id_t uwp_frame = unwind_protect::begin_frame (); std::string nm = file_name; @@ -3394,7 +3383,7 @@ std::string file; - unwind_protect_bool (fcn_file_from_relative_lookup); + unwind_protect::protect_var (fcn_file_from_relative_lookup); fcn_file_from_relative_lookup = false; @@ -3410,7 +3399,7 @@ if (autoload) { - unwind_protect_bool (autoloading); + unwind_protect::protect_var (autoloading); autoloading = true; } @@ -3433,8 +3422,8 @@ { // These are needed by yyparse. - unwind_protect_str (curr_fcn_file_name); - unwind_protect_str (curr_fcn_file_full_name); + unwind_protect::protect_var (curr_fcn_file_name); + unwind_protect::protect_var (curr_fcn_file_full_name); curr_fcn_file_name = nm; curr_fcn_file_full_name = file; @@ -3454,7 +3443,7 @@ } } - unwind_protect::run_frame ("load_fcn_from_file"); + unwind_protect::run_frame (uwp_frame); return retval; } @@ -3570,10 +3559,10 @@ { std::string file_full_name = file_ops::tilde_expand (file_name); - unwind_protect::begin_frame ("source_file"); - - unwind_protect_str (curr_fcn_file_name); - unwind_protect_str (curr_fcn_file_full_name); + unwind_protect::frame_id_t uwp_frame = unwind_protect::begin_frame (); + + unwind_protect::protect_var (curr_fcn_file_name); + unwind_protect::protect_var (curr_fcn_file_full_name); curr_fcn_file_name = file_name; curr_fcn_file_full_name = file_full_name; @@ -3588,7 +3577,7 @@ error ("source: context must be \"caller\" or \"base\""); if (! error_state) - unwind_protect::add (octave_call_stack::unwind_pop); + unwind_protect::add_fcn (octave_call_stack::pop); } if (! error_state) @@ -3622,7 +3611,7 @@ file_full_name.c_str ()); } - unwind_protect::run_frame ("source_file"); + unwind_protect::run_frame (uwp_frame); } DEFUN (mfilename, args, , @@ -3878,15 +3867,15 @@ { octave_value_list retval; - unwind_protect::begin_frame ("eval_string"); - - unwind_protect_int (input_line_number); - unwind_protect_int (current_input_column); - unwind_protect_bool (get_input_from_eval_string); - unwind_protect_bool (input_from_eval_string_pending); - unwind_protect_bool (parser_end_of_input); - unwind_protect_bool (line_editing); - unwind_protect_str (current_eval_string); + unwind_protect::frame_id_t uwp_frame = unwind_protect::begin_frame (); + + unwind_protect::protect_var (input_line_number); + unwind_protect::protect_var (current_input_column); + unwind_protect::protect_var (get_input_from_eval_string); + unwind_protect::protect_var (input_from_eval_string_pending); + unwind_protect::protect_var (parser_end_of_input); + unwind_protect::protect_var (line_editing); + unwind_protect::protect_var (current_eval_string); input_line_number = 1; current_input_column = 1; @@ -3900,8 +3889,8 @@ YY_BUFFER_STATE old_buf = current_buffer (); YY_BUFFER_STATE new_buf = create_buffer (0); - unwind_protect::add (restore_input_buffer, old_buf); - unwind_protect::add (delete_input_buffer, new_buf); + unwind_protect::add_fcn (switch_to_buffer, old_buf); + unwind_protect::add_fcn (delete_buffer, new_buf); switch_to_buffer (new_buf); @@ -3909,13 +3898,13 @@ { reset_parser (); - unwind_protect_ptr (global_command); + unwind_protect::protect_var (global_command); // Do this with an unwind-protect cleanup function so that the // forced variables will be unmarked in the event of an // interrupt. symbol_table::scope_id scope = symbol_table::top_scope (); - unwind_protect::add (symbol_table::unmark_forced_variables, &scope); + unwind_protect::add_fcn (symbol_table::unmark_forced_variables, scope); parse_status = yyparse (); @@ -3983,7 +3972,7 @@ } while (parse_status == 0); - unwind_protect::run_frame ("eval_string"); + unwind_protect::run_frame (uwp_frame); return retval; } @@ -4048,11 +4037,11 @@ if (nargin > 0) { - unwind_protect::begin_frame ("Feval"); + unwind_protect::frame_id_t uwp_frame = unwind_protect::begin_frame (); if (nargin > 1) { - unwind_protect_int (buffer_error_messages); + unwind_protect::protect_var (buffer_error_messages); buffer_error_messages++; } @@ -4078,7 +4067,7 @@ else if (nargout > 0) retval = tmp; - unwind_protect::run_frame ("Feval"); + unwind_protect::run_frame (uwp_frame); } else print_usage (); @@ -4186,7 +4175,7 @@ if (! error_state) { - unwind_protect::begin_frame ("Fassignin"); + unwind_protect::frame_id_t uwp_frame = unwind_protect::begin_frame (); if (context == "caller") octave_call_stack::goto_caller_frame (); @@ -4197,7 +4186,7 @@ if (! error_state) { - unwind_protect::add (octave_call_stack::unwind_pop); + unwind_protect::add_fcn (octave_call_stack::pop); std::string nm = args(1).string_value (); @@ -4212,7 +4201,7 @@ error ("assignin: expecting variable name as second argument"); } - unwind_protect::run_frame ("Fassignin"); + unwind_protect::run_frame (uwp_frame); } else error ("assignin: expecting string as first argument"); @@ -4241,7 +4230,7 @@ if (! error_state) { - unwind_protect::begin_frame ("Fevalin"); + unwind_protect::frame_id_t uwp_frame = unwind_protect::begin_frame (); if (context == "caller") octave_call_stack::goto_caller_frame (); @@ -4252,11 +4241,11 @@ if (! error_state) { - unwind_protect::add (octave_call_stack::unwind_pop); + unwind_protect::add_fcn (octave_call_stack::pop); if (nargin > 2) { - unwind_protect_int (buffer_error_messages); + unwind_protect::protect_var (buffer_error_messages); buffer_error_messages++; } @@ -4283,7 +4272,7 @@ } } - unwind_protect::run_frame ("Fevalin"); + unwind_protect::run_frame (uwp_frame); } else error ("evalin: expecting string as first argument"); diff -r 1de00ca9c9f2 -r 17af7cce7d1b src/pt-eval.cc --- a/src/pt-eval.cc Thu Jun 25 11:41:46 2009 +0200 +++ b/src/pt-eval.cc Thu Jun 25 13:57:38 2009 +0200 @@ -820,7 +820,7 @@ } static void -do_catch_code (void *ptr) +do_catch_code (tree_statement_list *list) { // Is it safe to call OCTAVE_QUIT here? We are already running // something on the unwind_protect stack, but the element for this @@ -845,8 +845,6 @@ if (octave_interrupt_immediately || octave_interrupt_state < 0) return; - tree_statement_list *list = static_cast (ptr); - // Set up for letting the user print any messages from errors that // occurred in the body of the try_catch statement. @@ -871,7 +869,7 @@ tree_statement_list *catch_code = cmd.cleanup (); - unwind_protect::add (do_catch_code, catch_code); + unwind_protect::add_fcn (do_catch_code, catch_code); tree_statement_list *try_code = cmd.body (); @@ -899,10 +897,8 @@ } static void -do_unwind_protect_cleanup_code (void *ptr) +do_unwind_protect_cleanup_code (tree_statement_list *list) { - tree_statement_list *list = static_cast (ptr); - unwind_protect::protect_var (octave_interrupt_state); octave_interrupt_state = 0; @@ -981,7 +977,7 @@ { tree_statement_list *cleanup_code = cmd.cleanup (); - unwind_protect::add (do_unwind_protect_cleanup_code, cleanup_code); + unwind_protect::add_fcn (do_unwind_protect_cleanup_code, cleanup_code); tree_statement_list *unwind_protect_code = cmd.body (); diff -r 1de00ca9c9f2 -r 17af7cce7d1b src/symtab.h --- a/src/symtab.h Thu Jun 25 11:41:46 2009 +0200 +++ b/src/symtab.h Thu Jun 25 13:57:38 2009 +0200 @@ -1311,7 +1311,7 @@ clear_functions (); } - static void clear_variables (scope_id scope = xcurrent_scope) + static void clear_variables (scope_id scope) { symbol_table *inst = get_instance (scope); @@ -1319,6 +1319,12 @@ inst->do_clear_variables (); } + // This is split for unwind_protect. + static void clear_variables (void) + { + clear_variables (xcurrent_scope); + } + static void clear_objects (scope_id scope = xcurrent_scope) { symbol_table *inst = get_instance (scope); @@ -1335,22 +1341,6 @@ inst->do_unmark_forced_variables (); } - // For unwind_protect. - static void unmark_forced_variables (void *arg) - { - // Unmark any symbols that may have been tagged as local variables - // while parsing (for example, by force_local_variable in lex.l). - - symbol_table::scope_id *p = static_cast (arg); - - if (p) - unmark_forced_variables (*p); -} - - - // For unwind_protect. - static void clear_variables (void *) { clear_variables (); } - static void clear_functions (void) { for (fcn_table_iterator p = fcn_table.begin (); p != fcn_table.end (); p++) diff -r 1de00ca9c9f2 -r 17af7cce7d1b src/toplev.cc --- a/src/toplev.cc Thu Jun 25 11:41:46 2009 +0200 +++ b/src/toplev.cc Thu Jun 25 13:57:38 2009 +0200 @@ -560,7 +560,7 @@ // the forced variables will be unmarked in the event of an // interrupt. symbol_table::scope_id scope = symbol_table::top_scope (); - unwind_protect::add_action_var (symbol_table::unmark_forced_variables, scope); + unwind_protect::add_fcn (symbol_table::unmark_forced_variables, scope); // This is the same as yyparse in parse.y. retval = octave_parse (); diff -r 1de00ca9c9f2 -r 17af7cce7d1b src/toplev.h --- a/src/toplev.h Thu Jun 25 11:41:46 2009 +0200 +++ b/src/toplev.h Thu Jun 25 13:57:38 2009 +0200 @@ -247,6 +247,11 @@ return instance_ok () ? instance->do_goto_frame (n, verbose) : false; } + static void restore_frame (size_t n) + { + goto_frame (n); + } + static bool goto_frame_relative (int n, bool verbose = false) { return instance_ok () @@ -277,10 +282,6 @@ instance->do_pop (); } - // A function for popping the top of the call stack that is suitable - // for use as an unwind_protect handler. - static void unwind_pop (void *) { pop (); } - static void clear (void) { if (instance_ok ()) diff -r 1de00ca9c9f2 -r 17af7cce7d1b src/unwind-prot.h --- a/src/unwind-prot.h Thu Jun 25 11:41:46 2009 +0200 +++ b/src/unwind-prot.h Thu Jun 25 13:57:38 2009 +0200 @@ -45,19 +45,51 @@ virtual ~elem (void) { } }; - // An element that merely runs a void (*)(void *) function. + // An element that merely runs a void (*)(void) function. class fcn_elem : public elem { public: - fcn_elem (void (*fptr) (void *), void *ptr) - : e_fptr (fptr), e_ptr (ptr) { } + fcn_elem (void (*fptr) (void)) + : e_fptr (fptr) { } - void run (void) { e_fptr (e_ptr); } + void run (void) { e_fptr (); } private: - void (*e_fptr) (void *); - void *e_ptr; + void (*e_fptr) (void); + }; + + // An element that stores a variable of type T along with a void (*) (T) + // function pointer, and calls the function with the parameter. + + template + class fcn_arg_elem : public elem + { + public: + fcn_arg_elem (void (*fcn) (T), T arg) + : e_fcn (fcn), e_arg (arg) { } + + void run (void) { e_fcn (e_arg); } + + private: + void (*e_fcn) (T); + T e_arg; + }; + + // An element for calling a member function. + + template + class method_elem : public elem + { + public: + method_elem (T *obj, void (T::*method) (void)) + : e_obj (obj), e_method (method) { } + + void run (void) { (e_obj->*e_method) (); } + + private: + T *e_obj; + void (T::*e_method) (void); }; // An element that stores arbitrary variable, and restores it. @@ -75,21 +107,19 @@ T *e_ptr, e_val; }; - // An element that stores a variable of type T along with a void (*) (T) - // function pointer, and calls the function with the parameter. + // Deletes a class allocated using new. template - class action_var_elem : public elem + class delete_ptr_elem : public elem { public: - action_var_elem (void (*fcn) (T), T val) - : e_fcn (fcn), e_val (val) { } + delete_ptr_elem (T *ptr) + : e_ptr (ptr) { } - void run (void) { e_fcn (e_val); } + void run (void) { delete e_ptr; } private: - void (*e_fcn) (T); - T e_val; + T *e_ptr; }; typedef size_t frame_id_t; @@ -161,9 +191,38 @@ tag_list.pop (); } + // For backward compatibility. static void add (void (*fcn) (void *), void *ptr = 0) { - elt_list.push (new fcn_elem (fcn, ptr)); + elt_list.push (new fcn_arg_elem (fcn, ptr)); + } + + // Call to void func (void). + static void add_fcn (void (*fcn) (void)) + { + elt_list.push (new fcn_elem (fcn)); + } + + // Call to void func (T). + template + static void add_fcn (void (*action) (T), T val) + { + elt_list.push (new fcn_arg_elem (action, val)); + } + + // Call to T::method (void). + template + static void add_method (T *obj, void (T::*method) (void)) + { + elt_list.push (new method_elem (obj, method)); + } + + // Call to delete (T*). + + template + static void add_delete (T *obj) + { + elt_list.push (new delete_ptr_elem (obj)); } // Protect any variable. @@ -180,13 +239,6 @@ elt_list.push (new restore_var_elem (var, val)); } - // Store a function pointer together with a single argument (passed by value). - template - static void add_action_var (void (*action) (T), T val) - { - elt_list.push (new action_var_elem (action, val)); - } - private: static std::stack elt_list; diff -r 1de00ca9c9f2 -r 17af7cce7d1b src/variables.cc --- a/src/variables.cc Thu Jun 25 11:41:46 2009 +0200 +++ b/src/variables.cc Thu Jun 25 13:57:38 2009 +0200 @@ -1389,14 +1389,14 @@ // Set up temporary scope. symbol_table::scope_id tmp_scope = symbol_table::alloc_scope (); - unwind_protect::add_action_var (symbol_table::erase_scope, tmp_scope); + unwind_protect::add_fcn (symbol_table::erase_scope, tmp_scope); symbol_table::set_scope (tmp_scope); octave_call_stack::push (tmp_scope, 0); - unwind_protect::add (octave_call_stack::unwind_pop, 0); + unwind_protect::add_fcn (octave_call_stack::pop); - unwind_protect::add (symbol_table::clear_variables); + unwind_protect::add_fcn (symbol_table::clear_variables); feval ("load", octave_value (nm), 0);