================
@@ -0,0 +1,229 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "ScriptedFrameProvider.h"
+#include "Plugins/Process/scripted/ScriptedFrame.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Interpreter/Interfaces/ScriptedFrameProviderInterface.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/ScriptedMetadata.h"
+#include "lldb/Utility/Status.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+
+using namespace lldb;
+using namespace lldb_private;
+
+void ScriptedFrameProvider::Initialize() {
+  PluginManager::RegisterPlugin(GetPluginNameStatic(),
+                                "Provides synthetic frames via scripting",
+                                nullptr, 
ScriptedFrameProvider::CreateInstance);
+}
+
+void ScriptedFrameProvider::Terminate() {
+  PluginManager::UnregisterPlugin(ScriptedFrameProvider::CreateInstance);
+}
+
+llvm::Expected<lldb::SyntheticFrameProviderSP>
+ScriptedFrameProvider::CreateInstance(
+    lldb::StackFrameListSP input_frames,
+    const SyntheticFrameProviderDescriptor &descriptor) {
+  if (!input_frames)
+    return llvm::createStringError(
+        "failed to create scripted frame: invalid input frames");
+
+  Thread &thread = input_frames->GetThread();
+  ProcessSP process_sp = thread.GetProcess();
+  if (!process_sp)
+    return nullptr;
+
+  if (!descriptor.IsValid())
+    return llvm::createStringError(
+        "failed to create scripted frame: invalid scripted metadata");
+
+  if (!descriptor.AppliesToThread(thread))
+    return nullptr;
+
+  Status error;
+  auto provider_sp = std::make_shared<ScriptedFrameProvider>(
+      input_frames, *descriptor.scripted_metadata_sp, error);
+  if (!provider_sp || error.Fail())
+    return error.ToError();
+
+  return provider_sp;
+}
+
+ScriptedFrameProvider::ScriptedFrameProvider(
+    StackFrameListSP input_frames, const ScriptedMetadata &scripted_metadata,
+    Status &error)
+    : SyntheticFrameProvider(input_frames), m_interface_sp(nullptr) {
+  if (!m_input_frames) {
+    error = Status::FromErrorString(
+        "cannot create scripted frame provider: Invalid input frames");
+    return;
+  }
+
+  ProcessSP process_sp = GetThread().GetProcess();
+  if (!process_sp) {
+    error = Status::FromErrorString(
+        "cannot create scripted frame provider: Invalid process");
+    return;
+  }
+
+  ScriptInterpreter *script_interp =
+      process_sp->GetTarget().GetDebugger().GetScriptInterpreter();
+  if (!script_interp) {
+    error = Status::FromErrorString("cannot create scripted frame provider: No 
"
+                                    "script interpreter installed");
+    return;
+  }
+
+  m_interface_sp = script_interp->CreateScriptedFrameProviderInterface();
+  if (!m_interface_sp) {
+    error = Status::FromErrorString(
+        "cannot create scripted frame provider: Script interpreter couldn't "
+        "create Scripted Frame Provider Interface");
+    return;
+  }
+
+  auto obj_or_err = m_interface_sp->CreatePluginObject(
+      scripted_metadata.GetClassName(), input_frames,
+      scripted_metadata.GetArgsSP());
+  if (!obj_or_err) {
+    error = Status::FromError(obj_or_err.takeError());
+    return;
+  }
+
+  StructuredData::ObjectSP object_sp = *obj_or_err;
+  if (!object_sp || !object_sp->IsValid()) {
+    error = Status::FromErrorString(
+        "cannot create scripted frame provider: Failed to create valid script "
+        "object");
+    return;
+  }
+
+  error.Clear();
+}
+
+ScriptedFrameProvider::~ScriptedFrameProvider() = default;
+
+llvm::Expected<StackFrameSP>
+ScriptedFrameProvider::GetFrameAtIndex(uint32_t idx) {
+  if (!m_interface_sp)
+    return llvm::createStringError(
+        "cannot get stack frame: Scripted frame provider not initialized");
+
+  auto create_frame_from_dict =
+      [this](StructuredData::Dictionary *dict,
+             uint32_t index) -> llvm::Expected<StackFrameSP> {
+    lldb::addr_t pc;
+    if (!dict->GetValueForKeyAsInteger("pc", pc))
+      return llvm::createStringError(
+          "missing 'pc' key from scripted frame dictionary.");
+
+    Address symbol_addr;
+    symbol_addr.SetLoadAddress(pc, &GetThread().GetProcess()->GetTarget());
+
+    lldb::addr_t cfa = LLDB_INVALID_ADDRESS;
+    bool cfa_is_valid = false;
----------------
JDevlieghere wrote:

How come these two are not const?

https://github.com/llvm/llvm-project/pull/161870
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to