LLDB mainline
ScriptedInterface.h
Go to the documentation of this file.
1//===-- ScriptedInterface.h -------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_INTERPRETER_INTERFACES_SCRIPTEDINTERFACE_H
10#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDINTERFACE_H
11
14
17#include "lldb/Utility/Log.h"
20#include "lldb/lldb-private.h"
21
22#include "llvm/Support/Compiler.h"
23
24#include <cassert>
25#include <optional>
26#include <string>
27
28namespace lldb_private {
30public:
31 ScriptedInterface() = default;
33
34 /// Delete the copy constructor. The copy would share the registry entry, and
35 /// the first one destroyed would unregister it while the other is still
36 /// alive.
37 /// @{
40 /// @}
41
45
46 const std::optional<ScriptedMetadata> &GetScriptedMetadata() const {
48 }
49
50 /// The name this interface is registered under with the PluginManager.
51 /// Every concrete scripted interface registers itself as a plugin, together
52 /// with the kind of extension it drives, so this name identifies that kind.
53 virtual llvm::StringRef GetPluginName() = 0;
54
55 /// Whether the user can invoke this extension directly, the way a scripted
56 /// command can. Those never introduce the target's API mutex bypass, so at
57 /// top level they serialize like any other command; nested inside an
58 /// already-bypassed callback every extension inherits the ambient policy.
59 virtual bool UserCanRunDirectly() const { return false; }
60
62 llvm::StringLiteral name;
63 size_t min_arg_count = 0;
64 };
65
66 virtual llvm::SmallVector<AbstractMethodRequirement>
68
69 /// Methods a script may legitimately leave out, for which LLDB has a
70 /// documented answer.
71 ///
72 /// This is the counterpart of GetAbstractMethodRequirements(): a method is
73 /// either required, and its absence rejects the class outright, or listed
74 /// here, and its absence is an expected answer. Only methods named here may
75 /// be dispatched with ScriptedPythonInterface::DispatchToOptional().
76 virtual llvm::SmallVector<llvm::StringLiteral> GetOptionalMethods() const {
77 return {};
78 }
79
80 virtual llvm::Expected<FileSpec> GetScriptedModulePath() {
81 return llvm::make_error<UnimplementedError>();
82 }
83
84 llvm::SmallVector<llvm::StringLiteral> const GetAbstractMethods() const {
85 llvm::SmallVector<llvm::StringLiteral> abstract_methods;
86 llvm::transform(GetAbstractMethodRequirements(), abstract_methods.begin(),
87 [](const AbstractMethodRequirement &requirement) {
88 return requirement.name;
89 });
90 return abstract_methods;
91 }
92
93 template <typename Ret>
94 static Ret ErrorWithMessage(llvm::StringRef caller_name,
95 llvm::StringRef user_msg, Status &error,
96 LLDBLog log_category = LLDBLog::Process) {
97 LLDB_LOGF(GetLog(log_category), "%s ERROR = %s", caller_name.data(),
98 user_msg.data());
99
100 // If `error` already has detailed content (e.g. a Python traceback),
101 // prepend this call's friendlier message to it instead of discarding
102 // either one.
103 std::string existing_error = error.Fail() ? error.AsCString() : "";
104 if (existing_error.empty())
105 error = Status::FromErrorString(user_msg.data());
106 else
107 error = Status::FromErrorStringWithFormatv("{0}: {1}", user_msg,
108 existing_error);
109
110 return {};
111 }
112
115 return false;
116 }
117
118protected:
120 std::string class_name, FileSpec source_path,
122 assert(registry_sp && "registering with an invalid registry");
123 assert(!m_registry_wp.lock() && "script object is already registered");
125 info.plugin_name = GetPluginName();
126 info.class_name = std::move(class_name);
128 info.object_address =
129 reinterpret_cast<uintptr_t>(m_object_instance_sp->GetValue());
130 info.source_path = std::move(source_path);
131 info.args_sp = std::move(args_sp);
132 m_registry_id = registry_sp->Add(std::move(info));
133 m_registry_wp = registry_sp;
134 }
135
137 std::optional<ScriptedMetadata> m_scripted_metadata;
138
139private:
141 // The interpreter owning the registry may already be gone.
142 if (auto registry_sp = m_registry_wp.lock())
143 registry_sp->Remove(m_registry_id);
144 m_registry_wp.reset();
145 }
146
148 uint64_t m_registry_id = 0;
149};
150} // namespace lldb_private
151
152#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDINTERFACE_H
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOGF(log,...)
Definition Log.h:389
A file utility class.
Definition FileSpec.h:56
virtual llvm::StringRef GetPluginName()=0
The name this interface is registered under with the PluginManager.
static Ret ErrorWithMessage(llvm::StringRef caller_name, llvm::StringRef user_msg, Status &error, LLDBLog log_category=LLDBLog::Process)
std::optional< ScriptedMetadata > m_scripted_metadata
llvm::SmallVector< llvm::StringLiteral > const GetAbstractMethods() const
virtual llvm::SmallVector< AbstractMethodRequirement > GetAbstractMethodRequirements() const =0
lldb::ScriptedInstanceRegistryWP m_registry_wp
virtual bool UserCanRunDirectly() const
Whether the user can invoke this extension directly, the way a scripted command can.
virtual llvm::Expected< FileSpec > GetScriptedModulePath()
StructuredData::GenericSP GetScriptObjectInstance()
ScriptedInterface & operator=(const ScriptedInterface &)=delete
static bool CreateInstance(lldb::ScriptLanguage language, ScriptedInterfaceUsages usages)
ScriptedInterface(const ScriptedInterface &)=delete
Delete the copy constructor.
void RegisterInstance(const lldb::ScriptedInstanceRegistrySP &registry_sp, std::string class_name, FileSpec source_path, StructuredData::DictionarySP args_sp)
virtual llvm::SmallVector< llvm::StringLiteral > GetOptionalMethods() const
Methods a script may legitimately leave out, for which LLDB has a documented answer.
const std::optional< ScriptedMetadata > & GetScriptedMetadata() const
StructuredData::GenericSP m_object_instance_sp
An error handling class.
Definition Status.h:118
static Status FromErrorString(const char *str)
Definition Status.h:141
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
Definition Status.h:151
std::shared_ptr< Generic > GenericSP
std::shared_ptr< Dictionary > DictionarySP
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:338
ScriptLanguage
Script interpreter types.
std::weak_ptr< lldb_private::ScriptedInstanceRegistry > ScriptedInstanceRegistryWP
std::shared_ptr< lldb_private::ScriptedInstanceRegistry > ScriptedInstanceRegistrySP
llvm::StringRef plugin_name
The interface's PluginManager name, from the string literal its GetPluginNameStatic() returns,...