Skip to content

[lldb] Add support for ScriptedFrame to provide values/variables.#178575

Merged
bzcheeseman merged 1 commit intomainfrom
users/bzcheeseman/stack/6
Jan 30, 2026
Merged

[lldb] Add support for ScriptedFrame to provide values/variables.#178575
bzcheeseman merged 1 commit intomainfrom
users/bzcheeseman/stack/6

Conversation

@bzcheeseman
Copy link
Contributor

@bzcheeseman bzcheeseman commented Jan 29, 2026

Stacked PRs:


[lldb] Add support for ScriptedFrame to provide values/variables.

This patch adds plumbing to support the implementations of StackFrame::Get{}Variable{} on ScriptedFrame. The major pieces required are:

  • A modification to ScriptedFrameInterface, so that we can actually call the python methods.
  • A corresponding update to the python implementation to call the python methods.
  • An implementation in ScriptedFrame that can get the variable list on construction inside ScriptedFrame::Create, and pass that list into the ScriptedFrame so it can get those values on request.

There is a major caveat, which is that if the values from the python side don't have variables attached, right now, they won't be passed into the scripted frame to be stored in the variable list. Future discussions around adding support for 'extended variables' when printing frame variables may create a reason to change the VariableListSP into a ValueObjectListSP, and generate the VariableListSP on the fly, but that should be addressed at a later time.

This patch also adds tests to the frame provider test suite to prove these changes all plumb together correctly.

Related radar: rdar://165708771

@llvmbot llvmbot added the lldb label Jan 29, 2026
@bzcheeseman bzcheeseman force-pushed the users/bzcheeseman/stack/6 branch from 8ccd0cf to e481f65 Compare January 29, 2026 03:00
@bzcheeseman bzcheeseman force-pushed the users/bzcheeseman/stack/5 branch from a11fcee to be1b9d1 Compare January 29, 2026 03:00
bzcheeseman added a commit that referenced this pull request Jan 29, 2026
This patch adds plumbing to support the implementations of StackFrame::Get{*}Variable{*} on ScriptedFrame. The major pieces required are:
- A modification to ScriptedFrameInterface, so that we can actually call the python methods.
- A corresponding update to the python implementation to call the python methods.
- An implementation in ScriptedFrame that can get the variable list on construction inside ScriptedFrame::Create, and pass that list into the ScriptedFrame so it can get those values on request.

There is a major caveat, which is that if the values from the python side don't have variables attached, right now, they won't be passed into the scripted frame to be stored in the variable list. Future discussions around adding support for 'extended variables' when printing frame variables may create a reason to change the VariableListSP into a ValueObjectListSP, and generate the VariableListSP on the fly, but that should be addressed at a later time.

This patch also adds tests to the frame provider test suite to prove these changes all plumb together correctly.

stack-info: PR: #178575, branch: users/bzcheeseman/stack/6
@llvmbot
Copy link
Member

llvmbot commented Jan 29, 2026

@llvm/pr-subscribers-lldb

Author: Aman LaChapelle (bzcheeseman)

Changes

Stacked PRs:

  • ->#178575
  • #178574
  • #178573

[lldb] Add support for ScriptedFrame to provide values/variables.

This patch adds plumbing to support the implementations of StackFrame::Get{}Variable{} on ScriptedFrame. The major pieces required are:

  • A modification to ScriptedFrameInterface, so that we can actually call the python methods.
  • A corresponding update to the python implementation to call the python methods.
  • An implementation in ScriptedFrame that can get the variable list on construction inside ScriptedFrame::Create, and pass that list into the ScriptedFrame so it can get those values on request.

There is a major caveat, which is that if the values from the python side don't have variables attached, right now, they won't be passed into the scripted frame to be stored in the variable list. Future discussions around adding support for 'extended variables' when printing frame variables may create a reason to change the VariableListSP into a ValueObjectListSP, and generate the VariableListSP on the fly, but that should be addressed at a later time.

This patch also adds tests to the frame provider test suite to prove these changes all plumb together correctly.


Full diff: https://github.com/llvm/llvm-project/pull/178575.diff

8 Files Affected:

  • (modified) lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameInterface.h (+11)
  • (modified) lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp (+72-5)
  • (modified) lldb/source/Plugins/Process/scripted/ScriptedFrame.h (+20-1)
  • (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.cpp (+27)
  • (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.h (+6)
  • (modified) lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py (+53)
  • (modified) lldb/test/API/functionalities/scripted_frame_provider/main.cpp (+4)
  • (modified) lldb/test/API/functionalities/scripted_frame_provider/test_frame_providers.py (+82)
diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameInterface.h
index 8ef4b37d6ba12..90170d3bead5f 100644
--- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameInterface.h
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameInterface.h
@@ -10,6 +10,7 @@
 #define LLDB_INTERPRETER_INTERFACES_SCRIPTEDFRAMEINTERFACE_H
 
 #include "ScriptedInterface.h"
+#include "lldb/API/SBValueList.h"
 #include "lldb/Core/StructuredDataImpl.h"
 #include "lldb/Symbol/SymbolContext.h"
 #include "lldb/lldb-private.h"
@@ -49,6 +50,16 @@ class ScriptedFrameInterface : virtual public ScriptedInterface {
   virtual std::optional<std::string> GetRegisterContext() {
     return std::nullopt;
   }
+
+  virtual std::optional<lldb::ValueObjectListSP> GetVariables() {
+    return std::nullopt;
+  }
+
+  virtual lldb::ValueObjectSP
+  GetValueObjectForVariableExpression(llvm::StringRef expr, uint32_t options,
+                                      Status &error) {
+    return nullptr;
+  }
 };
 } // namespace lldb_private
 
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp b/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp
index 70ce101c6c834..caf37dc71e03e 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp
+++ b/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp
@@ -9,6 +9,7 @@
 #include "ScriptedFrame.h"
 #include "Plugins/Process/Utility/RegisterContextMemory.h"
 
+#include "lldb/API/SBDeclaration.h"
 #include "lldb/Core/Address.h"
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/Module.h"
@@ -20,6 +21,7 @@
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/SymbolContext.h"
 #include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/VariableList.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/RegisterContext.h"
@@ -28,6 +30,8 @@
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/StructuredData.h"
+#include "lldb/ValueObject/ValueObject.h"
+#include "lldb/ValueObject/ValueObjectList.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -106,6 +110,30 @@ ScriptedFrame::Create(ThreadSP thread_sp,
   if (maybe_sym_ctx)
     sc = *maybe_sym_ctx;
 
+  // If we have any variables from the scripted interface, pull them out and add
+  // them to the ScriptedFrame object.
+  std::optional<ValueObjectListSP> maybe_variables =
+      scripted_frame_interface->GetVariables();
+  lldb::VariableListSP variable_list_sp = nullptr;
+  if (maybe_variables && *maybe_variables) {
+    variable_list_sp = std::make_shared<VariableList>();
+    ValueObjectListSP value_list_sp = *maybe_variables;
+
+    for (uint32_t i = 0, e = value_list_sp->GetSize(); i < e; ++i) {
+      ValueObjectSP v = value_list_sp->GetValueObjectAtIndex(i);
+      if (!v)
+        continue;
+
+      VariableSP var = v->GetVariable();
+      // TODO: We could in theory ask the scripted frame to *produce* a
+      //       variable for this value object.
+      if (!var)
+        continue;
+
+      variable_list_sp->AddVariable(var);
+    }
+  }
+
   lldb::RegisterContextSP reg_ctx_sp;
   auto regs_or_err =
       CreateRegisterContext(*scripted_frame_interface, *thread_sp, frame_id);
@@ -114,9 +142,10 @@ ScriptedFrame::Create(ThreadSP thread_sp,
   else
     reg_ctx_sp = *regs_or_err;
 
-  return std::make_shared<ScriptedFrame>(thread_sp, scripted_frame_interface,
-                                         frame_id, pc, sc, reg_ctx_sp,
-                                         owned_script_object_sp);
+  return std::make_shared<ScriptedFrame>(
+      thread_sp, scripted_frame_interface, frame_id, pc, sc, reg_ctx_sp,
+      owned_script_object_sp, variable_list_sp,
+      maybe_variables.value_or(nullptr));
 }
 
 ScriptedFrame::ScriptedFrame(ThreadSP thread_sp,
@@ -124,13 +153,16 @@ ScriptedFrame::ScriptedFrame(ThreadSP thread_sp,
                              lldb::user_id_t id, lldb::addr_t pc,
                              SymbolContext &sym_ctx,
                              lldb::RegisterContextSP reg_ctx_sp,
-                             StructuredData::GenericSP script_object_sp)
+                             StructuredData::GenericSP script_object_sp,
+                             lldb::VariableListSP variables_sp,
+                             lldb::ValueObjectListSP values_sp)
     : StackFrame(thread_sp, /*frame_idx=*/id,
                  /*concrete_frame_idx=*/id, /*reg_context_sp=*/reg_ctx_sp,
                  /*cfa=*/0, /*pc=*/pc,
                  /*behaves_like_zeroth_frame=*/!id, /*symbol_ctx=*/&sym_ctx),
       m_scripted_frame_interface_sp(interface_sp),
-      m_script_object_sp(script_object_sp) {
+      m_script_object_sp(script_object_sp), m_variable_list_sp(variables_sp),
+      m_value_objects_sp(values_sp) {
   // FIXME: This should be part of the base class constructor.
   m_stack_frame_kind = StackFrame::Kind::Synthetic;
 }
@@ -265,3 +297,38 @@ lldb::RegisterContextSP ScriptedFrame::GetRegisterContext() {
 
   return m_reg_context_sp;
 }
+
+VariableList *ScriptedFrame::GetVariableList(bool get_file_globals,
+                                             Status *error_ptr) {
+  return m_variable_list_sp.get();
+}
+
+lldb::VariableListSP
+ScriptedFrame::GetInScopeVariableList(bool get_file_globals,
+                                      bool must_have_valid_location) {
+  return m_variable_list_sp;
+}
+
+lldb::ValueObjectSP ScriptedFrame::GetValueObjectForFrameVariable(
+    const lldb::VariableSP &variable_sp, lldb::DynamicValueType use_dynamic) {
+  for (size_t i = 0, e = m_variable_list_sp->GetSize(); i < e; ++i) {
+    if (m_variable_list_sp->GetVariableAtIndex(i) == variable_sp) {
+      return m_value_objects_sp->GetValueObjectAtIndex(i);
+    }
+  }
+  return nullptr;
+}
+
+lldb::ValueObjectSP ScriptedFrame::GetValueForVariableExpressionPath(
+    llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
+    uint32_t options, lldb::VariableSP &var_sp, Status &error) {
+  // Unless the frame implementation knows how to create variables (which it
+  // doesn't), we can't construct anything for the variable. This may seem
+  // somewhat out of place, but it's basically because of how this API is used -
+  // the print command uses this API to fill in var_sp; and this implementation
+  // can't do that!
+  (void)var_sp;
+  // Otherwise, delegate to the scripted frame interface pointer.
+  return m_scripted_frame_interface_sp->GetValueObjectForVariableExpression(
+      var_expr, options, error);
+}
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedFrame.h b/lldb/source/Plugins/Process/scripted/ScriptedFrame.h
index 0545548e912e6..5aef8f58b1aae 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedFrame.h
+++ b/lldb/source/Plugins/Process/scripted/ScriptedFrame.h
@@ -26,7 +26,9 @@ class ScriptedFrame : public lldb_private::StackFrame {
                 lldb::ScriptedFrameInterfaceSP interface_sp,
                 lldb::user_id_t frame_idx, lldb::addr_t pc,
                 SymbolContext &sym_ctx, lldb::RegisterContextSP reg_ctx_sp,
-                StructuredData::GenericSP script_object_sp = nullptr);
+                StructuredData::GenericSP script_object_sp = nullptr,
+                lldb::VariableListSP variables_sp = nullptr,
+                lldb::ValueObjectListSP values_sp = nullptr);
 
   ~ScriptedFrame() override;
 
@@ -63,6 +65,21 @@ class ScriptedFrame : public lldb_private::StackFrame {
 
   lldb::RegisterContextSP GetRegisterContext() override;
 
+  VariableList *GetVariableList(bool get_file_globals,
+                                lldb_private::Status *error_ptr) override;
+
+  lldb::VariableListSP
+  GetInScopeVariableList(bool get_file_globals,
+                         bool must_have_valid_location = false) override;
+
+  lldb::ValueObjectSP
+  GetValueObjectForFrameVariable(const lldb::VariableSP &variable_sp,
+                                 lldb::DynamicValueType use_dynamic) override;
+
+  lldb::ValueObjectSP GetValueForVariableExpressionPath(
+      llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
+      uint32_t options, lldb::VariableSP &var_sp, Status &error) override;
+
   bool isA(const void *ClassID) const override {
     return ClassID == &ID || StackFrame::isA(ClassID);
   }
@@ -82,6 +99,8 @@ class ScriptedFrame : public lldb_private::StackFrame {
 
   lldb::ScriptedFrameInterfaceSP m_scripted_frame_interface_sp;
   lldb_private::StructuredData::GenericSP m_script_object_sp;
+  lldb::VariableListSP m_variable_list_sp;
+  lldb::ValueObjectListSP m_value_objects_sp;
 
   static char ID;
 };
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.cpp
index 20ca7a2c01356..3782d9729bbf9 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.cpp
@@ -154,4 +154,31 @@ std::optional<std::string> ScriptedFramePythonInterface::GetRegisterContext() {
   return obj->GetAsString()->GetValue().str();
 }
 
+std::optional<lldb::ValueObjectListSP>
+ScriptedFramePythonInterface::GetVariables() {
+  Status error;
+  auto vals = Dispatch<lldb::ValueObjectListSP>("get_variables", error);
+
+  if (error.Fail()) {
+    return ErrorWithMessage<lldb::ValueObjectListSP>(LLVM_PRETTY_FUNCTION,
+                                                     error.AsCString(), error);
+  }
+
+  return vals;
+}
+
+lldb::ValueObjectSP ScriptedFramePythonInterface::GetValueObjectForVariableExpression(
+    llvm::StringRef expr, uint32_t options, Status &status) {
+  Status dispatch_error;
+  auto val = Dispatch<lldb::ValueObjectSP>(
+      "get_value_for_variable_expression", dispatch_error, expr.data(), options, status);
+
+  if (dispatch_error.Fail()) {
+    return ErrorWithMessage<lldb::ValueObjectSP>(
+        LLVM_PRETTY_FUNCTION, dispatch_error.AsCString(), dispatch_error);
+  }
+
+  return val;
+}
+
 #endif
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.h
index 3aff237ae65d5..bb866c9146640 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.h
@@ -52,6 +52,12 @@ class ScriptedFramePythonInterface : public ScriptedFrameInterface,
   StructuredData::DictionarySP GetRegisterInfo() override;
 
   std::optional<std::string> GetRegisterContext() override;
+
+  std::optional<lldb::ValueObjectListSP> GetVariables() override;
+
+  lldb::ValueObjectSP
+  GetValueObjectForVariableExpression(llvm::StringRef expr, uint32_t options,
+                                      Status &status) override;
 };
 } // namespace lldb_private
 
diff --git a/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py b/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py
index 964d213b16887..7dd74013b90f8 100644
--- a/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py
+++ b/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py
@@ -730,3 +730,56 @@ def test_chained_frame_providers(self):
         frame3 = thread.GetFrameAtIndex(3)
         self.assertIsNotNone(frame3)
         self.assertIn("thread_func", frame3.GetFunctionName())
+
+    def test_get_values(self):
+        """Test a frame that provides values."""
+        self.build()
+        # Set the breakpoint after the variable_in_main variable exists and can be queried.
+        target, process, thread, bkpt = lldbutil.run_to_line_breakpoint(
+            self, lldb.SBFileSpec(self.source), 35, only_one_thread=False
+        )
+
+        # Get original frame count.
+        original_frame_count = thread.GetNumFrames()
+        self.assertGreaterEqual(
+            original_frame_count, 2, "Should have at least 2 real frames"
+        )
+
+        # Import the test frame providers.
+        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
+        self.runCmd("command script import " + script_path)
+
+        # Register a provider that can provide variables.
+        error = lldb.SBError()
+        target.RegisterScriptedFrameProvider(
+            "test_frame_providers.ValueProvidingFrameProvider",
+            lldb.SBStructuredData(),
+            error,
+        )
+        self.assertTrue(error.Success(), f"Failed to register provider: {error}")
+
+        # Verify we have 1 more frame.
+        new_frame_count = thread.GetNumFrames()
+        self.assertEqual(
+            new_frame_count,
+            original_frame_count + 1,
+            "Should have original frames + 1 extra frames",
+        )
+
+        # Check that we can get variables from this frame.
+        frame0 = thread.GetFrameAtIndex(0)
+        self.assertIsNotNone(frame0)
+        # Get every variable visible at this point
+        variables = frame0.GetVariables(True, True, True, False)
+        self.assertTrue(variables.IsValid() and variables.GetSize() == 1)
+
+        # Check that we can get values from paths. `_handler_one` is a special
+        # value we provide through only our expression handler in the frame
+        # implementation.
+        one = frame0.GetValueForVariablePath("_handler_one")
+        self.assertEqual(one.unsigned, 1)
+        var = frame0.GetValueForVariablePath("variable_in_main")
+        # The names won't necessarily match, but the values should (the frame renames the SBValue)
+        self.assertEqual(var.unsigned, variables.GetValueAtIndex(0).unsigned)
+        varp1 = frame0.GetValueForVariablePath("variable_in_main + 1")
+        self.assertEqual(varp1.unsigned, 124)
diff --git a/lldb/test/API/functionalities/scripted_frame_provider/main.cpp b/lldb/test/API/functionalities/scripted_frame_provider/main.cpp
index 0298e88e4de16..e1d346c29052b 100644
--- a/lldb/test/API/functionalities/scripted_frame_provider/main.cpp
+++ b/lldb/test/API/functionalities/scripted_frame_provider/main.cpp
@@ -29,6 +29,10 @@ void thread_func(int thread_num) {
 int main(int argc, char **argv) {
   std::thread threads[NUM_THREADS];
 
+  // Used as an existing C++ variable we can anchor on.
+  int variable_in_main = 123;
+  (void)variable_in_main;
+
   for (int i = 0; i < NUM_THREADS; i++) {
     threads[i] = std::thread(thread_func, i);
   }
diff --git a/lldb/test/API/functionalities/scripted_frame_provider/test_frame_providers.py b/lldb/test/API/functionalities/scripted_frame_provider/test_frame_providers.py
index 6233041f68a51..3a30e4fa96d6e 100644
--- a/lldb/test/API/functionalities/scripted_frame_provider/test_frame_providers.py
+++ b/lldb/test/API/functionalities/scripted_frame_provider/test_frame_providers.py
@@ -458,3 +458,85 @@ def get_frame_at_index(self, index):
             # Pass through input frames (shifted by 1)
             return index - 1
         return None
+
+
+class ValueProvidingFrame(ScriptedFrame):
+    """Scripted frame with a valid PC but no associated module."""
+
+    def __init__(self, thread, idx, pc, function_name, variable):
+        args = lldb.SBStructuredData()
+        super().__init__(thread, args)
+
+        self.idx = idx
+        self.pc = pc
+        self.function_name = function_name
+        self.variable = variable
+
+    def get_id(self):
+        """Return the frame index."""
+        return self.idx
+
+    def get_pc(self):
+        """Return the program counter."""
+        return self.pc
+
+    def get_function_name(self):
+        """Return the function name."""
+        return self.function_name
+
+    def is_artificial(self):
+        """Not artificial."""
+        return False
+
+    def is_hidden(self):
+        """Not hidden."""
+        return False
+
+    def get_register_context(self):
+        """No register context."""
+        return None
+
+    def get_variables(self):
+        """"""
+        out = lldb.SBValueList()
+        out.Append(self.variable)
+        return out
+
+    def get_value_for_variable_expression(self, expr, options, error: lldb.SBError):
+        out = lldb.SBValue()
+        if expr == "_handler_one":
+            out = self.variable.CreateValueFromExpression("_handler_one", "(uint32_t)1")
+        elif self.variable.name in expr:
+            out = self.variable.CreateValueFromExpression("_expr", expr)
+
+        if out.IsValid():
+            return out
+
+        error.SetErrorString(f"expression {expr} failed")
+        return None
+
+
+class ValueProvidingFrameProvider(ScriptedFrameProvider):
+    """Add a single 'value-provider' frame at the beginning."""
+
+    def __init__(self, input_frames, args):
+        super().__init__(input_frames, args)
+
+    @staticmethod
+    def get_description():
+        """Return a description of this provider."""
+        return "Add 'value-provider' frame at beginning"
+
+    def get_frame_at_index(self, index):
+        if index == 0:
+            f = self.input_frames.GetFrameAtIndex(index)
+            # Find some variable we can give to the frame.
+            variable = f.FindVariable("variable_in_main")
+            # Return synthetic "value-provider" frame
+            return ValueProvidingFrame(
+                self.thread, 0, 0xF00, "value-provider", variable
+            )
+        elif index - 1 < len(self.input_frames):
+            # Pass through input frames (shifted by 1)
+            return index - 1
+        return None

@github-actions
Copy link

github-actions bot commented Jan 29, 2026

✅ With the latest revision this PR passed the C/C++ code formatter.

@bzcheeseman bzcheeseman marked this pull request as draft January 29, 2026 05:18
@bzcheeseman bzcheeseman changed the base branch from users/bzcheeseman/stack/5 to main January 29, 2026 05:18
@bzcheeseman bzcheeseman force-pushed the users/bzcheeseman/stack/6 branch from e481f65 to eb2215a Compare January 29, 2026 05:18
bzcheeseman added a commit that referenced this pull request Jan 29, 2026
This patch adds plumbing to support the implementations of StackFrame::Get{*}Variable{*} on ScriptedFrame. The major pieces required are:
- A modification to ScriptedFrameInterface, so that we can actually call the python methods.
- A corresponding update to the python implementation to call the python methods.
- An implementation in ScriptedFrame that can get the variable list on construction inside ScriptedFrame::Create, and pass that list into the ScriptedFrame so it can get those values on request.

There is a major caveat, which is that if the values from the python side don't have variables attached, right now, they won't be passed into the scripted frame to be stored in the variable list. Future discussions around adding support for 'extended variables' when printing frame variables may create a reason to change the VariableListSP into a ValueObjectListSP, and generate the VariableListSP on the fly, but that should be addressed at a later time.

This patch also adds tests to the frame provider test suite to prove these changes all plumb together correctly.

stack-info: PR: #178575, branch: users/bzcheeseman/stack/6
@bzcheeseman bzcheeseman changed the base branch from main to users/bzcheeseman/stack/5 January 29, 2026 05:19
@bzcheeseman bzcheeseman marked this pull request as ready for review January 29, 2026 05:19
@bzcheeseman bzcheeseman marked this pull request as draft January 29, 2026 06:20
@bzcheeseman bzcheeseman changed the base branch from users/bzcheeseman/stack/5 to main January 29, 2026 06:20
@bzcheeseman bzcheeseman changed the base branch from main to users/bzcheeseman/stack/5 January 29, 2026 06:20
@bzcheeseman bzcheeseman marked this pull request as ready for review January 29, 2026 06:20
@bzcheeseman bzcheeseman marked this pull request as draft January 29, 2026 16:31
@bzcheeseman bzcheeseman changed the base branch from users/bzcheeseman/stack/5 to main January 29, 2026 16:31
@bzcheeseman bzcheeseman force-pushed the users/bzcheeseman/stack/6 branch from eb2215a to cd2c467 Compare January 29, 2026 16:31
@bzcheeseman bzcheeseman changed the base branch from main to users/bzcheeseman/stack/5 January 29, 2026 16:31
@bzcheeseman bzcheeseman marked this pull request as ready for review January 29, 2026 16:32
@bzcheeseman bzcheeseman marked this pull request as draft January 29, 2026 16:33
@bzcheeseman bzcheeseman changed the base branch from users/bzcheeseman/stack/5 to main January 29, 2026 16:33
@bzcheeseman bzcheeseman force-pushed the users/bzcheeseman/stack/6 branch from cd2c467 to c3d0c37 Compare January 29, 2026 16:33
@bzcheeseman bzcheeseman force-pushed the users/bzcheeseman/stack/6 branch from b46ed29 to 41eeb01 Compare January 29, 2026 19:58
@bzcheeseman bzcheeseman marked this pull request as ready for review January 29, 2026 19:58
Copy link
Member

@medismailben medismailben left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost there

@medismailben
Copy link
Member

Also, would you mind including rdar://165708771 at the end of the commit message, thanks.

@bzcheeseman bzcheeseman marked this pull request as draft January 29, 2026 21:18
@bzcheeseman bzcheeseman force-pushed the users/bzcheeseman/stack/6 branch from 41eeb01 to 88c0bf8 Compare January 29, 2026 21:18
@bzcheeseman bzcheeseman marked this pull request as ready for review January 29, 2026 21:18
@bzcheeseman
Copy link
Contributor Author

rdar://165708771

LOL still closing radars even after leaving Apple :P

@medismailben
Copy link
Member

rdar://165708771

LOL still closing radars even after leaving Apple :P

Looks like you can't avoid it :p

Copy link
Member

@medismailben medismailben left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with comment addressed :)

This patch adds plumbing to support the implementations of StackFrame::Get{*}Variable{*} on ScriptedFrame. The major pieces required are:
- A modification to ScriptedFrameInterface, so that we can actually call the python methods.
- A corresponding update to the python implementation to call the python methods.
- An implementation in ScriptedFrame that can get the variable list on construction inside ScriptedFrame::Create, and pass that list into the ScriptedFrame so it can get those values on request.

There is a major caveat, which is that if the values from the python side don't have variables attached, right now, they won't be passed into the scripted frame to be stored in the variable list. Future discussions around adding support for 'extended variables' when printing frame variables may create a reason to change the VariableListSP into a ValueObjectListSP, and generate the VariableListSP on the fly, but that should be addressed at a later time.

This patch also adds tests to the frame provider test suite to prove these changes all plumb together correctly.

Related radar: rdar://165708771

stack-info: PR: #178575, branch: users/bzcheeseman/stack/6
@bzcheeseman bzcheeseman marked this pull request as draft January 30, 2026 01:53
@bzcheeseman bzcheeseman force-pushed the users/bzcheeseman/stack/6 branch from 88c0bf8 to 5d52734 Compare January 30, 2026 01:54
@bzcheeseman bzcheeseman marked this pull request as ready for review January 30, 2026 01:54
@bzcheeseman bzcheeseman merged commit 10f2611 into main Jan 30, 2026
10 of 11 checks passed
@bzcheeseman bzcheeseman deleted the users/bzcheeseman/stack/6 branch January 30, 2026 05:24
honeygoyal pushed a commit to honeygoyal/llvm-project that referenced this pull request Jan 30, 2026
…vm#178575)

This patch adds plumbing to support the implementations of StackFrame::Get{*}Variable{*} on ScriptedFrame. The major pieces required are:
- A modification to ScriptedFrameInterface, so that we can actually call the python methods.
- A corresponding update to the python implementation to call the python methods.
- An implementation in ScriptedFrame that can get the variable list on construction inside ScriptedFrame::Create, and pass that list into the ScriptedFrame so it can get those values on request.

There is a major caveat, which is that if the values from the python side don't have variables attached, right now, they won't be passed into the scripted frame to be stored in the variable list. Future discussions around adding support for 'extended variables' when printing frame variables may create a reason to change the VariableListSP into a ValueObjectListSP, and generate the VariableListSP on the fly, but that should be addressed at a later time.

This patch also adds tests to the frame provider test suite to prove these changes all plumb together correctly.

Related radar: rdar://165708771
@medismailben medismailben added this to the LLVM 22.x Release milestone Feb 3, 2026
@medismailben
Copy link
Member

/cherry-pick 10f2611

@llvmbot
Copy link
Member

llvmbot commented Feb 3, 2026

Failed to cherry-pick: 10f2611

https://github.com/llvm/llvm-project/actions/runs/21639721323

Please manually backport the fix and push it to your github fork. Once this is done, please create a pull request

medismailben pushed a commit to medismailben/llvm-project that referenced this pull request Feb 3, 2026
…vm#178575)

This patch adds plumbing to support the implementations of StackFrame::Get{*}Variable{*} on ScriptedFrame. The major pieces required are:
- A modification to ScriptedFrameInterface, so that we can actually call the python methods.
- A corresponding update to the python implementation to call the python methods.
- An implementation in ScriptedFrame that can get the variable list on construction inside ScriptedFrame::Create, and pass that list into the ScriptedFrame so it can get those values on request.

There is a major caveat, which is that if the values from the python side don't have variables attached, right now, they won't be passed into the scripted frame to be stored in the variable list. Future discussions around adding support for 'extended variables' when printing frame variables may create a reason to change the VariableListSP into a ValueObjectListSP, and generate the VariableListSP on the fly, but that should be addressed at a later time.

This patch also adds tests to the frame provider test suite to prove these changes all plumb together correctly.

Related radar: rdar://165708771

(cherry picked from commit 10f2611)
sshrestha-aa pushed a commit to sshrestha-aa/llvm-project that referenced this pull request Feb 4, 2026
…vm#178575)

This patch adds plumbing to support the implementations of StackFrame::Get{*}Variable{*} on ScriptedFrame. The major pieces required are:
- A modification to ScriptedFrameInterface, so that we can actually call the python methods.
- A corresponding update to the python implementation to call the python methods.
- An implementation in ScriptedFrame that can get the variable list on construction inside ScriptedFrame::Create, and pass that list into the ScriptedFrame so it can get those values on request.

There is a major caveat, which is that if the values from the python side don't have variables attached, right now, they won't be passed into the scripted frame to be stored in the variable list. Future discussions around adding support for 'extended variables' when printing frame variables may create a reason to change the VariableListSP into a ValueObjectListSP, and generate the VariableListSP on the fly, but that should be addressed at a later time.

This patch also adds tests to the frame provider test suite to prove these changes all plumb together correctly.

Related radar: rdar://165708771
c-rhodes pushed a commit to llvmbot/llvm-project that referenced this pull request Feb 9, 2026
…vm#178575)

This patch adds plumbing to support the implementations of StackFrame::Get{*}Variable{*} on ScriptedFrame. The major pieces required are:
- A modification to ScriptedFrameInterface, so that we can actually call the python methods.
- A corresponding update to the python implementation to call the python methods.
- An implementation in ScriptedFrame that can get the variable list on construction inside ScriptedFrame::Create, and pass that list into the ScriptedFrame so it can get those values on request.

There is a major caveat, which is that if the values from the python side don't have variables attached, right now, they won't be passed into the scripted frame to be stored in the variable list. Future discussions around adding support for 'extended variables' when printing frame variables may create a reason to change the VariableListSP into a ValueObjectListSP, and generate the VariableListSP on the fly, but that should be addressed at a later time.

This patch also adds tests to the frame provider test suite to prove these changes all plumb together correctly.

Related radar: rdar://165708771

(cherry picked from commit 10f2611)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Development

Successfully merging this pull request may close these issues.

3 participants