Mercurial > octave
changeset 32261:6d2f6ca0996f
VM fix unwind table for ignored outputs
Exception in nested expression erronously executed opcode CLEAR_IGNORE_OUTPUT
when unwinding. E.g. '[~, a] = deal (error("qwe"), 1)';
* parse-tree/pt-bytecode-walk.cc: Set proper instruction offset in unwind table
* parse-tree/pt-bytecode-walk.h: New field
* test/compile/bytecode_multi_assign.m: Update tests
author | Petter T. |
---|---|
date | Wed, 09 Aug 2023 12:57:05 +0200 |
parents | 5d9311556111 |
children | 7bb3358d89ae |
files | libinterp/parse-tree/pt-bytecode-walk.cc libinterp/parse-tree/pt-bytecode-walk.h test/compile/bytecode_multi_assign.m |
diffstat | 3 files changed, 29 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/parse-tree/pt-bytecode-walk.cc Wed Aug 09 12:56:03 2023 +0200 +++ b/libinterp/parse-tree/pt-bytecode-walk.cc Wed Aug 09 12:57:05 2023 +0200 @@ -2474,6 +2474,13 @@ rhs->accept (*this); // Walks rhs for NARGOUT elements + if (m_pending_ignore_outputs) + { + // The outer expression in rhs should have set m_ignored_ip_start to its ip offset. + CHECK (m_ignored_ip_start); + UNWIND (D.m_idx_unwind).m_ip_start = m_ignored_ip_start; + } + if (DEPTH () != 1) TODO ("Only root multi assignment supported now"); @@ -2512,6 +2519,7 @@ { m_pending_ignore_outputs = 0; m_v_ignored.clear (); + m_ignored_ip_start = 0; } POP_NARGOUT (); @@ -3669,6 +3677,7 @@ PUSH_CODE (m_ignored_of_total); for (int i : m_v_ignored) PUSH_CODE (i); + m_ignored_ip_start = CODE_SIZE (); // visit_multi_assignment () need the code offset to set the proper range for the unwind protect } if (id.is_postfix_indexed ()) @@ -4308,6 +4317,7 @@ PUSH_CODE (m_ignored_of_total); for (int i : m_v_ignored) PUSH_CODE (i); + m_ignored_ip_start = CODE_SIZE (); // visit_multi_assignment () need the code offset to set the proper range for the unwind protect } int loc_id = N_LOC (); @@ -4574,6 +4584,7 @@ PUSH_CODE (m_ignored_of_total); for (int i : m_v_ignored) PUSH_CODE (i); + m_ignored_ip_start = CODE_SIZE (); // visit_multi_assignment () need the code offset to set the proper range for the unwind protect } int nargout = NARGOUT ();
--- a/libinterp/parse-tree/pt-bytecode-walk.h Wed Aug 09 12:56:03 2023 +0200 +++ b/libinterp/parse-tree/pt-bytecode-walk.h Wed Aug 09 12:57:05 2023 +0200 @@ -184,6 +184,7 @@ bool m_pending_ignore_outputs = false; int m_ignored_of_total = 0; std::vector<int> m_v_ignored; + int m_ignored_ip_start = 0; // bool m_is_folding = false;
--- a/test/compile/bytecode_multi_assign.m Wed Aug 09 12:56:03 2023 +0200 +++ b/test/compile/bytecode_multi_assign.m Wed Aug 09 12:57:05 2023 +0200 @@ -46,6 +46,14 @@ __printf_assert__ ("%d ", C{1}); __printf_assert__ ("%d ", C{2}); __printf_assert__ ("%d ", D); + + % Check that opcodes SET_IGNORE_OUTPUTS and CLEAR_IGNORE_OUTPUTS + % does not mess up if a nested expression throws before SET_IGNORE_OUTPUTS + % is executed. + try + [~, b] = bar (baz_throws ()); + catch + end end function [a,b,c,d] = foo () @@ -54,3 +62,12 @@ c = 3; d = 4; end + +function [a b] = bar (c) + a = 1; + b = 0; +end + +function a = baz_throws () + error ("qwe"); +end \ No newline at end of file