https://github.com/kastiglione updated https://github.com/llvm/llvm-project/pull/182155
>From 42d68784f790cff9e223f84b60a5da7ee5877830 Mon Sep 17 00:00:00 2001 From: Dave Lee <[email protected]> Date: Wed, 18 Feb 2026 13:42:38 -0800 Subject: [PATCH 1/2] [lldb] Update the calling convention of BytecodeSyntheticChildren This changes how "self" is constructed, where "self" is the data placed on the stack before calls to `num_children`, `get_child_at_index`, etc. First, the return value of `init` is saved to its own member, `m_init_results`. Likewise, the return value of `update` is saved to a separate member, `m_update_results`. Calls to both `init` and `update` recieve only the value object on their stack. This is done to simplify implementations of `update`. It makes them more "pure", in that the argument is always a single value (the value object). Previously `update` was called with the value of "self", which was shared between `init` and `update`, and was mutated by `update`. Lastly, the results of `init` and `update` are concatenated to being the value of "self" when calling other methods. --- .../lldb/DataFormatters/TypeSynthetic.h | 10 ++++++- lldb/source/DataFormatters/TypeSynthetic.cpp | 30 ++++++++++++------- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/lldb/include/lldb/DataFormatters/TypeSynthetic.h b/lldb/include/lldb/DataFormatters/TypeSynthetic.h index fbf1d060a92b2..ae51ab400ba3d 100644 --- a/lldb/include/lldb/DataFormatters/TypeSynthetic.h +++ b/lldb/include/lldb/DataFormatters/TypeSynthetic.h @@ -502,9 +502,17 @@ class BytecodeSyntheticChildren : public SyntheticChildren { lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override; llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override; + private: + /// The data stack representing "self". The value of "self" is the results + /// of `init` combined with the results of `update`. Together, these values + /// are placed on the stack when calling `num_children`, + /// `get_child_at_index`, etc. + FormatterBytecode::DataStack GetSelf(); + private: const SyntheticBytecodeImplementation &m_impl; - FormatterBytecode::DataStack m_self; + FormatterBytecode::DataStack m_init_results; + FormatterBytecode::DataStack m_update_results; }; public: diff --git a/lldb/source/DataFormatters/TypeSynthetic.cpp b/lldb/source/DataFormatters/TypeSynthetic.cpp index 10655cdca6f05..6e5721f357c6a 100644 --- a/lldb/source/DataFormatters/TypeSynthetic.cpp +++ b/lldb/source/DataFormatters/TypeSynthetic.cpp @@ -20,8 +20,10 @@ #include "lldb/Symbol/CompilerType.h" #include "lldb/Target/Target.h" #include "lldb/Utility/StreamString.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/Error.h" #include <cstdint> +#include <iterator> using namespace lldb; using namespace lldb_private; @@ -258,13 +260,11 @@ std::string ScriptedSyntheticChildren::GetDescription() { BytecodeSyntheticChildren::FrontEnd::FrontEnd( ValueObject &backend, SyntheticBytecodeImplementation &impl) : SyntheticChildrenFrontEnd(backend), m_impl(impl) { - FormatterBytecode::DataStack data(backend.GetSP()); - if (!m_impl.init) { - m_self = std::move(data); + if (!m_impl.init) return; - } FormatterBytecode::ControlStack control = {m_impl.init->getBuffer()}; + FormatterBytecode::DataStack data = {backend.GetSP()}; llvm::Error error = FormatterBytecode::Interpret(control, data, FormatterBytecode::sig_init); if (error) { @@ -274,7 +274,7 @@ BytecodeSyntheticChildren::FrontEnd::FrontEnd( } if (data.size() > 0) - m_self = std::move(data); + m_init_results = std::move(data); } lldb::ChildCacheState BytecodeSyntheticChildren::FrontEnd::Update() { @@ -282,7 +282,7 @@ lldb::ChildCacheState BytecodeSyntheticChildren::FrontEnd::Update() { return ChildCacheState::eRefetch; FormatterBytecode::ControlStack control = {m_impl.update->getBuffer()}; - FormatterBytecode::DataStack data = m_self; + FormatterBytecode::DataStack data = {m_backend.GetSP()}; llvm::Error error = FormatterBytecode::Interpret( control, data, FormatterBytecode::sig_update); if (error) { @@ -292,7 +292,7 @@ lldb::ChildCacheState BytecodeSyntheticChildren::FrontEnd::Update() { } if (data.size() > 0) - m_self = std::move(data); + m_update_results = std::move(data); return ChildCacheState::eRefetch; } @@ -303,7 +303,7 @@ BytecodeSyntheticChildren::FrontEnd::CalculateNumChildren() { return 0; FormatterBytecode::ControlStack control = {m_impl.num_children->getBuffer()}; - FormatterBytecode::DataStack data = m_self; + FormatterBytecode::DataStack data = GetSelf(); llvm::Error error = FormatterBytecode::Interpret( control, data, FormatterBytecode::sig_get_num_children); if (error) @@ -335,7 +335,7 @@ BytecodeSyntheticChildren::FrontEnd::GetChildAtIndex(uint32_t idx) { FormatterBytecode::ControlStack control = { m_impl.get_child_at_index->getBuffer()}; - FormatterBytecode::DataStack data = m_self; + FormatterBytecode::DataStack data = GetSelf(); data.emplace_back((uint64_t)idx); llvm::Error error = FormatterBytecode::Interpret( control, data, FormatterBytecode::sig_get_child_at_index); @@ -365,7 +365,7 @@ BytecodeSyntheticChildren::FrontEnd::GetIndexOfChildWithName(ConstString name) { FormatterBytecode::ControlStack control = { m_impl.get_child_index->getBuffer()}; - FormatterBytecode::DataStack data = m_self; + FormatterBytecode::DataStack data = GetSelf(); data.emplace_back(name.GetString()); llvm::Error error = FormatterBytecode::Interpret( control, data, FormatterBytecode::sig_get_child_index); @@ -391,6 +391,16 @@ BytecodeSyntheticChildren::FrontEnd::GetIndexOfChildWithName(ConstString name) { return llvm::createStringError("@get_child_index returned invalid value"); } +FormatterBytecode::DataStack BytecodeSyntheticChildren::FrontEnd::GetSelf() { + FormatterBytecode::DataStack self; + llvm::copy(m_init_results, std::back_inserter(self)); + llvm::copy(m_update_results, std::back_inserter(self)); + if (self.empty()) + // As a fallback, "self" is just the valobj. + self.emplace_back(m_backend.GetSP()); + return self; +} + std::string BytecodeSyntheticChildren::GetDescription() { StreamString sstr; sstr.Printf("%s%s%s Bytecode synthetic", Cascades() ? "" : " (not cascading)", >From f339e01b060bda57824072de9783ee2860709111 Mon Sep 17 00:00:00 2001 From: Dave Lee <[email protected]> Date: Wed, 18 Feb 2026 16:00:53 -0800 Subject: [PATCH 2/2] Update formatterbytecode.rst --- lldb/docs/resources/formatterbytecode.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/docs/resources/formatterbytecode.rst b/lldb/docs/resources/formatterbytecode.rst index f6a7b66fa728e..5ceeedab60b99 100644 --- a/lldb/docs/resources/formatterbytecode.rst +++ b/lldb/docs/resources/formatterbytecode.rst @@ -223,7 +223,7 @@ Signature Mnemonic Stack Effect 0x03 ``@get_child_index`` ``(Object+ String -> UInt)`` 0x04 ``@get_child_at_index`` ``(Object+ UInt -> Object)`` 0x05 ``@get_value`` ``(Object+ -> String)`` - 0x06 ``@update`` ``(Object+ -> Object+)`` + 0x06 ``@update`` ``(Object -> Object+)`` ========= ========================= ============================== If not specified, the init function defaults to an empty function that just passes the Object along. Its results may be cached and allow common prep work to be done for an Object that can be reused by subsequent calls to the other methods. This way subsequent calls to ``@get_child_at_index`` can avoid recomputing shared information, for example. _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
