# HG changeset patch # User Petter T. # Fri Mar 15 20:48:10 2024 +0100 # Branch bytecode-interpreter # Node ID 9787611d7c0fc1732decc3eceb8b9953a03664f5 # Parent fc12a2717ecfe060bcc4d45a50527bb354e9527a Fix errors' stack info wipwipwip not possible to apply diff -r fc12a2717ecf -r 9787611d7c0f libinterp/parse-tree/pt-bytecode-vm.cc --- a/libinterp/parse-tree/pt-bytecode-vm.cc Tue Mar 12 19:31:24 2024 +0100 +++ b/libinterp/parse-tree/pt-bytecode-vm.cc Fri Mar 15 20:48:10 2024 +0100 @@ -1242,7 +1242,7 @@ std::string fn_name = unwind_data->m_name; (*sp++).pee = new execution_exception {"error", "Octave:invalid-fun-call", fn_name + ": function called with too many inputs"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); ip++; // unwind expects ip to point to two after the opcode being executed goto unwind; } @@ -1251,7 +1251,7 @@ std::string fn_name = unwind_data->m_name; (*sp++).pee = new execution_exception {"error", "Octave:invalid-fun-call", fn_name + ": function called with too many outputs"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); ip++; goto unwind; } @@ -1358,7 +1358,7 @@ if (vararg_defined && !ov_vararg.iscell ()) { (*sp++).pee = new execution_exception {"error","","varargout must be a cell array object"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } } @@ -3466,7 +3466,7 @@ if (!is_ignored) { (*sp++).pee = new execution_exception {"error", "", "element number " + std::to_string (n_actual + 1) + " undefined in return list"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } } @@ -3742,7 +3742,7 @@ if (ov.is_undefined ()) { (*sp++).pee = new execution_exception {"error","","invalid use of 'end': may only be used to index existing value"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } @@ -3785,7 +3785,7 @@ if (ov.is_undefined ()) { (*sp++).pee = new execution_exception {"error","","invalid use of 'end': may only be used to index existing value"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } @@ -3854,7 +3854,7 @@ if (is_undef && i + 1 == n_ids) { (*sp++).pee = new execution_exception {"error","","invalid use of 'end': may only be used to index existing value"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } else if (is_undef) @@ -4036,7 +4036,7 @@ (*sp++).i = 1; // Need two native ints on the stack so they can be popped by the unwind. (*sp++).i = 2; (*sp++).pee = new execution_exception {"error", "", "in statement 'for [X, Y] = VAL', VAL must be a structure"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } @@ -4519,7 +4519,7 @@ if (i_col_idx && i_col_idx != n_cols) { (*sp++).pee = new execution_exception {"error","","number of columns must match"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } @@ -4534,7 +4534,7 @@ if (i_col_idx && i_col_idx != n_cols) { (*sp++).pee = new execution_exception {"error","","number of columns must match"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } @@ -4947,7 +4947,7 @@ if (n_returns >= 0 && nargout > n_returns) { (*sp++).pee = new execution_exception {"error","","function called with too many outputs"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } @@ -4992,7 +4992,7 @@ if (sp + stack_min_for_new_call >= m_stack + stack_size) { (*sp++).pee = new execution_exception {"error","","VM is running out of stack space"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } /* We are now going to call another function */ @@ -5146,7 +5146,7 @@ (*sp++).pee = new execution_exception {"error", "Octave:invalid-fun-call", fn_name + ": function called with over 512 inputs." " Consider using varargin."}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); //TODO: Remove error? goto unwind; } if (n_args_on_callee_stack > n_args_callee) @@ -5154,7 +5154,7 @@ std::string fn_name = unwind_data->m_name; (*sp++).pee = new execution_exception {"error", "Octave:invalid-fun-call", fn_name + ": function called with too many inputs"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } /* N_RETURNS is negative for varargout */ @@ -5164,7 +5164,7 @@ std::string fn_name = unwind_data->m_name; (*sp++).pee = new execution_exception {"error", "Octave:invalid-fun-call", fn_name + ": function called with too many outputs"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } @@ -5210,6 +5210,8 @@ m_ip = ip - code; m_unwind_data = unwind_data; + m_tw->set_active_bytecode_ip (ip - code); // Needed for backtrace source loc + m_echo_prior_op_was_cond = false; // Used by the echo functionality // Ther error_type is put on the stack before the jump to unwind. @@ -5444,7 +5446,7 @@ { (*sp++).pee = new execution_exception {"error", "", "can't make persistent variable '" + name + "' global"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } @@ -5477,7 +5479,7 @@ { (*sp++).pee = new execution_exception {"error", "", "can't make global variable '" + name + "' persistent"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } @@ -5546,7 +5548,7 @@ { (*sp++).pee = new execution_exception {"error", "", "in computed assignment A OP= X, A must be defined first"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } @@ -5740,7 +5742,7 @@ (*sp++).pee = new execution_exception {e}; } - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } else @@ -6273,7 +6275,7 @@ { (*sp++).pee = new execution_exception {"error", "", "invalid number of output arguments for constant expression"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } @@ -6600,7 +6602,7 @@ if (k + nel > n) { (*sp++).pee = new execution_exception {"error", "", "some elements undefined in return list"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } @@ -6688,7 +6690,7 @@ if (!is_ignored) { (*sp++).pee = new execution_exception {"error", "", "element number " + std::to_string (k + 1) + " undefined in return list"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } } @@ -6755,7 +6757,7 @@ if (! is_black_hole) { (*sp++).pee = new execution_exception {"error", "", "element number " + std::to_string (i_lhs + 1) + " undefined in return list"}; - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } @@ -7551,7 +7553,7 @@ case octave_base_value::vm_call_dispatch_type::OCT_FN_LOOKUP: { (*sp++).pee = new execution_exception {"error", "", "invalid undefined value in chained index expression"}; // TODO: Uninformative? - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } case octave_base_value::vm_call_dispatch_type::OCT_SUBSREF: @@ -7642,7 +7644,7 @@ if (! fcn) { (*sp++).pee = new execution_exception {"error", "", "invalid return value in chained index expression"}; // TODO: Uninformative? - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } else if (fcn->is_compiled ()) @@ -7822,7 +7824,7 @@ if (! fcn) { (*sp++).pee = new execution_exception {"error", "", "invalid return value in chained index expression"}; // TODO: Uninformative? - (*sp++).i = static_cast (error_type::EXECUTION_EXC); + (*sp++).i = static_cast (error_type::NEW_EXECUTION_EXC); goto unwind; } #if 0 // TODO: Support for bytecode calls to ctors @@ -7959,6 +7961,10 @@ "Octave:undefined-function", ss.str ()}; + std::list stack_info = m_tw->backtrace_info (); + stack_info.unique (); + e.set_stack_info (stack_info); + // Since the exception was made in the VM it has not been saved yet es.save_exception (e); @@ -7972,6 +7978,10 @@ execution_exception e {"error", "", ss.str ()}; + std::list stack_info = m_tw->backtrace_info (); + stack_info.unique (); + e.set_stack_info (stack_info); + es.save_exception (e); break; @@ -7989,6 +7999,23 @@ break; } + case error_type::NEW_EXECUTION_EXC: + { + execution_exception *e = m_sp [-1].pee; + + std::list stack_info = m_tw->backtrace_info (); + stack_info.unique (); + e->set_stack_info (stack_info); + + CHECK (e); + es.save_exception (*e); + + delete e; + + m_sp--; + + break; + } case error_type::EXECUTION_EXC: { execution_exception *e = m_sp [-1].pee; @@ -8012,6 +8039,10 @@ { execution_exception e {"error", "", "invalid number of elements on RHS of assignment"}; + std::list stack_info = m_tw->backtrace_info (); + stack_info.unique (); + e.set_stack_info (stack_info); + es.save_exception (e); break; @@ -8020,6 +8051,10 @@ { execution_exception e {"error", "", "value on right hand side of assignment is undefined"}; + std::list stack_info = m_tw->backtrace_info (); + stack_info.unique (); + e.set_stack_info (stack_info); + es.save_exception (e); break; diff -r fc12a2717ecf -r 9787611d7c0f libinterp/parse-tree/pt-bytecode.h --- a/libinterp/parse-tree/pt-bytecode.h Tue Mar 12 19:31:24 2024 +0100 +++ b/libinterp/parse-tree/pt-bytecode.h Fri Mar 15 20:48:09 2024 +0100 @@ -352,6 +352,7 @@ BAD_ALLOC, EXIT_EXCEPTION, DEBUG_QUIT, + NEW_EXECUTION_EXC, // Like EXECUTION_EXC, but thrown in the vm and not in call to error() }; enum class global_type