================ @@ -0,0 +1,232 @@ +//===-- ScriptedFrameProvider.cpp ----------------------------------------===// +// +// 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", + ScriptedFrameProvider::CreateInstance); +} + +void ScriptedFrameProvider::Terminate() { + PluginManager::UnregisterPlugin(ScriptedFrameProvider::CreateInstance); +} + +llvm::Expected<lldb::SyntheticFrameProviderSP> +ScriptedFrameProvider::CreateInstance(lldb::ThreadSP thread_sp) { + if (!thread_sp) + return llvm::createStringError( + "failed to create scripted frame: invalid thread"); + + ProcessSP process_sp = thread_sp->GetProcess(); + if (!process_sp) + return nullptr; + + Target &target = process_sp->GetTarget(); + + Status error; + if (auto descriptor = target.GetScriptedFrameProviderDescriptor()) { + if (!descriptor->IsValid()) + return llvm::createStringError( + "failed to create scripted frame: invalid scripted metadata"); + + if (!descriptor->AppliesToThread(thread_sp->GetID())) + return nullptr; + + auto provider_sp = std::make_shared<ScriptedFrameProvider>( + thread_sp, *descriptor->scripted_metadata_sp, error); + if (!provider_sp || error.Fail()) + return error.ToError(); + + return provider_sp; + } + + return llvm::createStringError( + "failed to create scripted frame: invalid scripted metadata"); +} + +ScriptedFrameProvider::ScriptedFrameProvider( + ThreadSP thread_sp, const ScriptedMetadata &scripted_metadata, + Status &error) + : SyntheticFrameProvider(thread_sp), m_interface_sp(nullptr) { + if (!m_thread_sp) { + error = Status::FromErrorString( + "cannot create scripted frame provider: Invalid thread"); + return; + } + + ProcessSP process_sp = m_thread_sp->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(), m_thread_sp, + 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(StackFrameListSP real_frames, + uint32_t idx) { + if (!m_interface_sp) + return llvm::createStringError( + "cannot get stack frame: Scripted frame provider not initialized"); + + auto create_frame_from_dict = ---------------- jimingham wrote:
Do you gain anything by having these be closures rather than methods? They make the function harder to read because you have to peer past these definitions first, and so far as I can tell, they only capture "this" and so are really just methods. https://github.com/llvm/llvm-project/pull/161870 _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
