================ @@ -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
