llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Med Ismail Bennani (medismailben)

<details>
<summary>Changes</summary>

This patch introduces a new scripting affordance in lldb: `ScriptedFrame`.

This allows user to produce mock stackframes in scripted threads and
scripted processes from a python script.

With this change, StackFrame can be synthetized from different sources:
- Either from a dictionary containing a load address, and a frame index,
  which is the legacy way.
- Or by creating a ScriptedFrame python object.

One particularity of synthezising stackframes from the ScriptedFrame
python object, is that these frame have an optional PC, meaning that
they don't have a report a valid PC and they can act as shells that just
contain static information, like the frame function name, the list of
variables or registers, etc. It can also provide a symbol context.

rdar://157260006

Signed-off-by: Med Ismail Bennani &lt;ismail@<!-- -->bennani.ma&gt;


---

Patch is 47.64 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/149622.diff


25 Files Affected:

- (modified) lldb/bindings/python/python-wrapper.swig (+1) 
- (modified) lldb/examples/python/templates/scripted_process.py (+136) 
- (modified) lldb/include/lldb/API/SBSymbolContext.h (+1) 
- (added) lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameInterface.h 
(+55) 
- (modified) lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadInterface.h 
(+10) 
- (modified) lldb/include/lldb/Interpreter/ScriptInterpreter.h (+5) 
- (modified) lldb/include/lldb/Target/StackFrame.h (+17-17) 
- (modified) lldb/include/lldb/lldb-forward.h (+3) 
- (modified) lldb/source/Core/FormatEntity.cpp (+1-1) 
- (modified) lldb/source/Plugins/Process/scripted/CMakeLists.txt (+1) 
- (added) lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp (+191) 
- (added) lldb/source/Plugins/Process/scripted/ScriptedFrame.h (+63) 
- (modified) lldb/source/Plugins/Process/scripted/ScriptedThread.cpp (+71-11) 
- (modified) lldb/source/Plugins/Process/scripted/ScriptedThread.h (+4-1) 
- (modified) 
lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt (+1) 
- (modified) 
lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h
 (+1) 
- (added) 
lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.cpp
 (+157) 
- (added) 
lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedFramePythonInterface.h
 (+59) 
- (modified) 
lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
 (+2-1) 
- (modified) 
lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp
 (+17) 
- (modified) 
lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.h
 (+5) 
- (modified) 
lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp (+5) 
- (modified) 
lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h (+2) 
- (modified) lldb/source/Symbol/LineEntry.cpp (+1-3) 
- (modified) 
lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py 
(+74-1) 


``````````diff
diff --git a/lldb/bindings/python/python-wrapper.swig 
b/lldb/bindings/python/python-wrapper.swig
index 2c30d536a753d..c0ad456bc12e8 100644
--- a/lldb/bindings/python/python-wrapper.swig
+++ b/lldb/bindings/python/python-wrapper.swig
@@ -519,6 +519,7 @@ void 
*lldb_private::python::LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyOb
   return sb_ptr;
 }
 
+
 void 
*lldb_private::python::LLDBSWIGPython_CastPyObjectToSBExecutionContext(PyObject 
*
                                                                     data) {
   lldb::SBExecutionContext *sb_ptr = NULL;
diff --git a/lldb/examples/python/templates/scripted_process.py 
b/lldb/examples/python/templates/scripted_process.py
index b6360b8519077..49059d533f38a 100644
--- a/lldb/examples/python/templates/scripted_process.py
+++ b/lldb/examples/python/templates/scripted_process.py
@@ -383,6 +383,142 @@ def get_extended_info(self):
         """
         return self.extended_info
 
+    def get_scripted_frame_plugin(self):
+        """Get scripted frame plugin name.
+
+        Returns:
+            str: Name of the scripted frame plugin.
+        """
+        return None
+
+
+class ScriptedFrame(metaclass=ABCMeta):
+    """
+    The base class for a scripted frame.
+
+    Most of the base class methods are `@abstractmethod` that need to be
+    overwritten by the inheriting class.
+    """
+
+    @abstractmethod
+    def __init__(self, thread, args):
+        """Construct a scripted frame.
+
+        Args:
+            thread (ScriptedThread): The thread owning this frame.
+            args (lldb.SBStructuredData): A Dictionary holding arbitrary
+                key/value pairs used by the scripted frame.
+        """
+        self.target = None
+        self.originating_thread = None
+        self.thread = None
+        self.args = None
+        self.id = None
+        self.name = None
+        self.register_info = None
+        self.register_ctx = {}
+        self.variables = []
+
+        if (
+            isinstance(thread, ScriptedThread)
+            or isinstance(thread, lldb.SBThread)
+            and thread.IsValid()
+        ):
+            self.target = thread.target
+            self.process = thread.process
+            self.originating_thread = thread
+            self.thread = self.process.GetThreadByIndexID(thread.tid)
+            self.get_register_info()
+
+    @abstractmethod
+    def get_id(self):
+        """Get the scripted frame identifier.
+
+        Returns:
+            int: The identifier of the scripted frame in the scripted thread.
+        """
+        pass
+
+    def get_pc(self):
+        """Get the scripted frame address.
+
+        Returns:
+            int: The optional address of the scripted frame in the scripted 
thread.
+        """
+        return None
+
+    def get_symbol_context(self):
+        """Get the scripted frame symbol context.
+
+        Returns:
+            lldb.SBSymbolContext: The symbol context of the scripted frame in 
the scripted thread.
+        """
+        return None
+
+    def is_inlined(self):
+        """Check if the scripted frame is inlined.
+
+        Returns:
+            bool: True if scripted frame is inlined. False otherwise.
+        """
+        return False
+
+    def is_artificial(self):
+        """Check if the scripted frame is artificial.
+
+        Returns:
+            bool: True if scripted frame is artificial. False otherwise.
+        """
+        return True
+
+    def is_hidden(self):
+        """Check if the scripted frame is hidden.
+
+        Returns:
+            bool: True if scripted frame is hidden. False otherwise.
+        """
+        return False
+
+    def get_function_name(self):
+        """Get the scripted frame function name.
+
+        Returns:
+            str: The function name of the scripted frame.
+        """
+        return self.name
+
+    def get_display_function_name(self):
+        """Get the scripted frame display function name.
+
+        Returns:
+            str: The display function name of the scripted frame.
+        """
+        return self.get_function_name()
+
+    def get_variables(self, filters):
+        """Get the scripted thread state type.
+
+        Args:
+            filter (lldb.SBVariablesOptions): The filter used to resolve the 
variables
+        Returns:
+            lldb.SBValueList: The SBValueList containing the SBValue for each 
resolved variable.
+                              Returns None by default.
+        """
+        return None
+
+    def get_register_info(self):
+        if self.register_info is None:
+            self.register_info = self.originating_thread.get_register_info()
+        return self.register_info
+
+    @abstractmethod
+    def get_register_context(self):
+        """Get the scripted thread register context
+
+        Returns:
+            str: A byte representing all register's value.
+        """
+        pass
 
 class PassthroughScriptedProcess(ScriptedProcess):
     driving_target = None
diff --git a/lldb/include/lldb/API/SBSymbolContext.h 
b/lldb/include/lldb/API/SBSymbolContext.h
index 128b0b65b7860..19f29c629d094 100644
--- a/lldb/include/lldb/API/SBSymbolContext.h
+++ b/lldb/include/lldb/API/SBSymbolContext.h
@@ -66,6 +66,7 @@ class LLDB_API SBSymbolContext {
   friend class SBTarget;
   friend class SBSymbolContextList;
 
+  friend class lldb_private::ScriptInterpreter;
   friend class lldb_private::python::SWIGBridge;
 
   SBSymbolContext(const lldb_private::SymbolContext &sc_ptr);
diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameInterface.h 
b/lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameInterface.h
new file mode 100644
index 0000000000000..8ef4b37d6ba12
--- /dev/null
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedFrameInterface.h
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_INTERPRETER_INTERFACES_SCRIPTEDFRAMEINTERFACE_H
+#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDFRAMEINTERFACE_H
+
+#include "ScriptedInterface.h"
+#include "lldb/Core/StructuredDataImpl.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/lldb-private.h"
+#include <optional>
+#include <string>
+
+namespace lldb_private {
+class ScriptedFrameInterface : virtual public ScriptedInterface {
+public:
+  virtual llvm::Expected<StructuredData::GenericSP>
+  CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx,
+                     StructuredData::DictionarySP args_sp,
+                     StructuredData::Generic *script_obj = nullptr) = 0;
+
+  virtual lldb::user_id_t GetID() { return LLDB_INVALID_FRAME_ID; }
+
+  virtual lldb::addr_t GetPC() { return LLDB_INVALID_ADDRESS; }
+
+  virtual std::optional<SymbolContext> GetSymbolContext() {
+    return std::nullopt;
+  }
+
+  virtual std::optional<std::string> GetFunctionName() { return std::nullopt; }
+
+  virtual std::optional<std::string> GetDisplayFunctionName() {
+    return std::nullopt;
+  }
+
+  virtual bool IsInlined() { return false; }
+
+  virtual bool IsArtificial() { return false; }
+
+  virtual bool IsHidden() { return false; }
+
+  virtual StructuredData::DictionarySP GetRegisterInfo() { return {}; }
+
+  virtual std::optional<std::string> GetRegisterContext() {
+    return std::nullopt;
+  }
+};
+} // namespace lldb_private
+
+#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDFRAMEINTERFACE_H
diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadInterface.h 
b/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadInterface.h
index a7cfc690b67dc..bc58f344d36f8 100644
--- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadInterface.h
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadInterface.h
@@ -44,6 +44,16 @@ class ScriptedThreadInterface : virtual public 
ScriptedInterface {
   }
 
   virtual StructuredData::ArraySP GetExtendedInfo() { return {}; }
+
+  virtual std::optional<std::string> GetScriptedFramePluginName() {
+    return std::nullopt;
+  }
+
+protected:
+  friend class ScriptedFrame;
+  virtual lldb::ScriptedFrameInterfaceSP CreateScriptedFrameInterface() {
+    return {};
+  }
 };
 } // namespace lldb_private
 
diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h 
b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
index dffb9b82abf3d..024bbc90a9a39 100644
--- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -26,6 +26,7 @@
 #include "lldb/Host/PseudoTerminal.h"
 #include "lldb/Host/StreamFile.h"
 #include "lldb/Interpreter/Interfaces/OperatingSystemInterface.h"
+#include "lldb/Interpreter/Interfaces/ScriptedFrameInterface.h"
 #include "lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h"
 #include "lldb/Interpreter/Interfaces/ScriptedProcessInterface.h"
 #include "lldb/Interpreter/Interfaces/ScriptedThreadInterface.h"
@@ -531,6 +532,10 @@ class ScriptInterpreter : public PluginInterface {
     return {};
   }
 
+  virtual lldb::ScriptedFrameInterfaceSP CreateScriptedFrameInterface() {
+    return {};
+  }
+
   virtual lldb::ScriptedThreadPlanInterfaceSP
   CreateScriptedThreadPlanInterface() {
     return {};
diff --git a/lldb/include/lldb/Target/StackFrame.h 
b/lldb/include/lldb/Target/StackFrame.h
index 4ffbf97ce6e90..cdbe8ae3c6779 100644
--- a/lldb/include/lldb/Target/StackFrame.h
+++ b/lldb/include/lldb/Target/StackFrame.h
@@ -398,7 +398,7 @@ class StackFrame : public ExecutionContextScope,
   ///
   /// \return
   ///   true if this is an inlined frame.
-  bool IsInlined();
+  virtual bool IsInlined();
 
   /// Query whether this frame is synthetic.
   bool IsSynthetic() const;
@@ -409,12 +409,12 @@ class StackFrame : public ExecutionContextScope,
   /// Query whether this frame is artificial (e.g a synthesized result of
   /// inferring missing tail call frames from a backtrace). Artificial frames
   /// may have limited support for inspecting variables.
-  bool IsArtificial() const;
+  virtual bool IsArtificial() const;
 
   /// Query whether this frame should be hidden from backtraces. Frame
   /// recognizers can customize this behavior and hide distracting
   /// system implementation details this way.
-  bool IsHidden();
+  virtual bool IsHidden();
 
   /// Language plugins can use this API to report language-specific
   /// runtime information about this compile unit, such as additional
@@ -425,13 +425,13 @@ class StackFrame : public ExecutionContextScope,
   ///
   ///  /// \return
   ///   A C-String containing the function demangled name. Can be null.
-  const char *GetFunctionName();
+  virtual const char *GetFunctionName();
 
   /// Get the frame's demangled display name.
   ///
   ///  /// \return
   ///   A C-String containing the function demangled display name. Can be null.
-  const char *GetDisplayFunctionName();
+  virtual const char *GetDisplayFunctionName();
 
   /// Query this frame to find what frame it is in this Thread's
   /// StackFrameList.
@@ -543,18 +543,7 @@ class StackFrame : public ExecutionContextScope,
 
   bool HasCachedData() const;
 
-private:
-  /// Private methods, called from GetValueForVariableExpressionPath.
-  /// See that method for documentation of parameters and return value.
-  lldb::ValueObjectSP LegacyGetValueForVariableExpressionPath(
-      llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
-      uint32_t options, lldb::VariableSP &var_sp, Status &error);
-
-  lldb::ValueObjectSP DILGetValueForVariableExpressionPath(
-      llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
-      uint32_t options, lldb::VariableSP &var_sp, Status &error);
-
-  /// For StackFrame only.
+  /// For StackFrame and derived classes only.
   /// \{
   lldb::ThreadWP m_thread_wp;
   uint32_t m_frame_index;
@@ -591,6 +580,17 @@ class StackFrame : public ExecutionContextScope,
   StreamString m_disassembly;
   std::recursive_mutex m_mutex;
 
+private:
+  /// Private methods, called from GetValueForVariableExpressionPath.
+  /// See that method for documentation of parameters and return value.
+  lldb::ValueObjectSP LegacyGetValueForVariableExpressionPath(
+      llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
+      uint32_t options, lldb::VariableSP &var_sp, Status &error);
+
+  lldb::ValueObjectSP DILGetValueForVariableExpressionPath(
+      llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
+      uint32_t options, lldb::VariableSP &var_sp, Status &error);
+
   StackFrame(const StackFrame &) = delete;
   const StackFrame &operator=(const StackFrame &) = delete;
 };
diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index 483dce98ea427..af5656b3dcad1 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -187,6 +187,7 @@ class SaveCoreOptions;
 class Scalar;
 class ScriptInterpreter;
 class ScriptInterpreterLocker;
+class ScriptedFrameInterface;
 class ScriptedMetadata;
 class ScriptedBreakpointInterface;
 class ScriptedPlatformInterface;
@@ -408,6 +409,8 @@ typedef std::shared_ptr<lldb_private::RecognizedStackFrame>
 typedef std::shared_ptr<lldb_private::ScriptSummaryFormat>
     ScriptSummaryFormatSP;
 typedef std::shared_ptr<lldb_private::ScriptInterpreter> ScriptInterpreterSP;
+typedef std::shared_ptr<lldb_private::ScriptedFrameInterface>
+    ScriptedFrameInterfaceSP;
 typedef std::shared_ptr<lldb_private::ScriptedMetadata> ScriptedMetadataSP;
 typedef std::unique_ptr<lldb_private::ScriptedPlatformInterface>
     ScriptedPlatformInterfaceUP;
diff --git a/lldb/source/Core/FormatEntity.cpp 
b/lldb/source/Core/FormatEntity.cpp
index 2ff73979e4976..491f5c6320d97 100644
--- a/lldb/source/Core/FormatEntity.cpp
+++ b/lldb/source/Core/FormatEntity.cpp
@@ -1681,7 +1681,7 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
       StackFrame *frame = exe_ctx->GetFramePtr();
       if (frame) {
         const Address &pc_addr = frame->GetFrameCodeAddress();
-        if (pc_addr.IsValid()) {
+        if (pc_addr.IsValid() || frame->IsSynthetic()) {
           if (DumpAddressAndContent(s, sc, exe_ctx, pc_addr, false))
             return true;
         }
diff --git a/lldb/source/Plugins/Process/scripted/CMakeLists.txt 
b/lldb/source/Plugins/Process/scripted/CMakeLists.txt
index 590166591a41e..1516ad3132e3b 100644
--- a/lldb/source/Plugins/Process/scripted/CMakeLists.txt
+++ b/lldb/source/Plugins/Process/scripted/CMakeLists.txt
@@ -1,6 +1,7 @@
 add_lldb_library(lldbPluginScriptedProcess PLUGIN
   ScriptedProcess.cpp
   ScriptedThread.cpp
+  ScriptedFrame.cpp
 
   LINK_COMPONENTS
     BinaryFormat
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp 
b/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp
new file mode 100644
index 0000000000000..6519df9185df0
--- /dev/null
+++ b/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp
@@ -0,0 +1,191 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ScriptedFrame.h"
+
+#include "lldb/Utility/DataBufferHeap.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void ScriptedFrame::CheckInterpreterAndScriptObject() const {
+  lldbassert(m_script_object_sp && "Invalid Script Object.");
+  lldbassert(GetInterface() && "Invalid Scripted Frame Interface.");
+}
+
+llvm::Expected<std::shared_ptr<ScriptedFrame>>
+ScriptedFrame::Create(ScriptedThread &thread,
+                      StructuredData::DictionarySP args_sp,
+                      StructuredData::Generic *script_object) {
+  if (!thread.IsValid())
+    return llvm::createStringError("Invalid scripted thread.");
+
+  thread.CheckInterpreterAndScriptObject();
+
+  auto scripted_frame_interface =
+      thread.GetInterface()->CreateScriptedFrameInterface();
+  if (!scripted_frame_interface)
+    return llvm::createStringError("failed to create scripted frame 
interface");
+
+  llvm::StringRef frame_class_name;
+  if (!script_object) {
+    std::optional<std::string> class_name =
+        thread.GetInterface()->GetScriptedFramePluginName();
+    if (!class_name || class_name->empty())
+      return llvm::createStringError(
+          "failed to get scripted thread class name");
+    frame_class_name = *class_name;
+  }
+
+  ExecutionContext exe_ctx(thread);
+  auto obj_or_err = scripted_frame_interface->CreatePluginObject(
+      frame_class_name, exe_ctx, args_sp, script_object);
+
+  if (!obj_or_err)
+    return llvm::createStringError(
+        "failed to create script object: %s",
+        llvm::toString(obj_or_err.takeError()).c_str());
+
+  StructuredData::GenericSP owned_script_object_sp = *obj_or_err;
+
+  if (!owned_script_object_sp->IsValid())
+    return llvm::createStringError("created script object is invalid");
+
+  lldb::user_id_t frame_id = scripted_frame_interface->GetID();
+
+  lldb::addr_t pc = scripted_frame_interface->GetPC();
+  SymbolContext sc;
+  Address symbol_addr;
+  if (pc != LLDB_INVALID_ADDRESS) {
+    symbol_addr.SetLoadAddress(pc, &thread.GetProcess()->GetTarget());
+    symbol_addr.CalculateSymbolContext(&sc);
+  }
+
+  std::optional<SymbolContext> maybe_sym_ctx =
+      scripted_frame_interface->GetSymbolContext();
+  if (maybe_sym_ctx) {
+    sc = *maybe_sym_ctx;
+  }
+
+  StructuredData::DictionarySP reg_info =
+      scripted_frame_interface->GetRegisterInfo();
+
+  if (!reg_info)
+    return llvm::createStringError(
+        "failed to get scripted thread registers info");
+
+  std::shared_ptr<DynamicRegisterInfo> register_info_sp =
+      DynamicRegisterInfo::Create(
+          *reg_info, thread.GetProcess()->GetTarget().GetArchitecture());
+
+  lldb::RegisterContextSP reg_ctx_sp;
+
+  std::optional<std::string> reg_data =
+      scripted_frame_interface->GetRegisterContext();
+  if (reg_data) {
+    DataBufferSP data_sp(
+        std::make_shared<DataBufferHeap>(reg_data->c_str(), reg_data->size()));
+
+    if (!data_sp->GetByteSize())
+      return llvm::createStringError("failed to copy raw registers data");
+
+    std::shared_ptr<RegisterContextMemory> reg_ctx_memory =
+        std::make_shared<RegisterContextMemory>(
+            thread, frame_id, *register_info_sp, LLDB_INVALID_ADDRESS);
+    if (!reg_ctx_memory)
+      return llvm::createStringError("failed to create a register context.");
+
+    reg_ctx_memory->SetAllRegisterData(data_sp);
+    reg_ctx_sp = reg_ctx_memory;
+  }
+
+  return std::make_shared<ScriptedFrame>(
+      thread, scripted_frame_interface, frame_id, pc, sc, reg_ctx_sp,
+      register_info_sp, owned_script_object_sp);
+}
+
+ScriptedFrame::ScriptedFrame(ScriptedThread &thread,
+                             ScriptedFrameInterfaceSP interface_sp,
+                             lldb::user_id_t id, lldb::addr_t pc,
+                             SymbolContext &sym_ctx,
+                             lldb::RegisterContextSP reg_ctx_sp,
+                             std::shared_ptr<DynamicRegisterInfo> reg_info_sp,
+                             StructuredData::GenericSP script_object_sp)
+    : StackFrame(thread.shared_from_this(), /*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_register_info_sp(reg_info_sp) {}
+
+ScriptedFrame::~ScriptedFrame() {}
+
+const char *ScriptedFrame::GetFunctionName() {
+  CheckInterpreterAndScriptObject();
+  std::optional<std::string> function_name = GetInterface()->GetFunctionName();
+  if (!function_name)
+    return nullptr;
+  return ConstString(function_name->c_str()).AsCString();
+}
+
+const char *ScriptedFrame::GetDisplayFunctionName() {
+  CheckInterpreterAndScriptObject();
+  std::optional<std::string> function_name =
+      GetInterface()->GetDisplayFunctionName();
+  if...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/149622
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to