LLDB mainline
ScriptedPythonInterface.h
Go to the documentation of this file.
1//===-- ScriptedPythonInterface.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_SOURCE_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPYTHONINTERFACE_H
10#define LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPYTHONINTERFACE_H
11
12#include <optional>
13#include <sstream>
14#include <tuple>
15#include <type_traits>
16#include <utility>
17
20
22#include "../SWIGPythonBridge.h"
24
25namespace lldb_private {
28public:
30 ~ScriptedPythonInterface() override = default;
31
40
42
50
52 std::variant<std::monostate, InvalidArgumentCountPayload> payload;
53 };
54
55 llvm::Expected<FileSpec> GetScriptedModulePath() override {
56 using namespace python;
58
61
63 return llvm::createStringError("scripted Interface has invalid object");
64
65 PythonObject py_obj =
66 PythonObject(PyRefType::Borrowed,
67 static_cast<PyObject *>(m_object_instance_sp->GetValue()));
68
69 if (!py_obj.IsAllocated())
70 return llvm::createStringError(
71 "scripted Interface has invalid python object");
72
73 PythonObject py_obj_class = py_obj.GetAttributeValue("__class__");
74 if (!py_obj_class.IsValid())
75 return llvm::createStringError(
76 "scripted Interface python object is missing '__class__' attribute");
77
78 PythonObject py_obj_module = py_obj_class.GetAttributeValue("__module__");
79 if (!py_obj_module.IsValid())
80 return llvm::createStringError(
81 "scripted Interface python object '__class__' is missing "
82 "'__module__' attribute");
83
84 PythonString py_obj_module_str = py_obj_module.Str();
85 if (!py_obj_module_str.IsValid())
86 return llvm::createStringError(
87 "scripted Interface python object '__class__.__module__' attribute "
88 "is not a string");
89
90 llvm::StringRef py_obj_module_str_ref = py_obj_module_str.GetString();
91 PythonModule py_module = PythonModule::AddModule(py_obj_module_str_ref);
92 if (!py_module.IsValid())
93 return llvm::createStringError("failed to import '%s' module",
94 py_obj_module_str_ref.data());
95
96 PythonObject py_module_file = py_module.GetAttributeValue("__file__");
97 if (!py_module_file.IsValid())
98 return llvm::createStringError(
99 "module '%s' is missing '__file__' attribute",
100 py_obj_module_str_ref.data());
101
102 PythonString py_module_file_str = py_module_file.Str();
103 if (!py_module_file_str.IsValid())
104 return llvm::createStringError(
105 "module '%s.__file__' attribute is not a string",
106 py_obj_module_str_ref.data());
107
108 return FileSpec(py_module_file_str.GetString());
109 }
110
111 llvm::Expected<std::map<llvm::StringLiteral, AbstractMethodCheckerPayload>>
113 const python::PythonDictionary &class_dict) const {
114
115 using namespace python;
116
117 std::map<llvm::StringLiteral, AbstractMethodCheckerPayload> checker;
118#define SET_CASE_AND_CONTINUE(method_name, case) \
119 { \
120 checker[method_name] = {case, {}}; \
121 continue; \
122 }
123
124 for (const AbstractMethodRequirement &requirement :
126 llvm::StringLiteral method_name = requirement.name;
127 if (!class_dict.HasKey(method_name))
128 SET_CASE_AND_CONTINUE(method_name,
130 llvm::Expected<PythonObject> callable_or_err =
131 class_dict.GetItem(method_name);
132 if (!callable_or_err) {
133 llvm::consumeError(callable_or_err.takeError());
134 SET_CASE_AND_CONTINUE(method_name,
136 }
137
138 PythonCallable callable = callable_or_err->AsType<PythonCallable>();
139 if (!callable)
140 SET_CASE_AND_CONTINUE(method_name,
142
143 if (!requirement.min_arg_count)
145
146 auto arg_info_or_err = callable.GetArgInfo();
147 if (!arg_info_or_err) {
148 llvm::consumeError(arg_info_or_err.takeError());
149 SET_CASE_AND_CONTINUE(method_name,
151 }
152
153 PythonCallable::ArgInfo arg_info = *arg_info_or_err;
154 if (requirement.min_arg_count <= arg_info.max_positional_args) {
156 } else {
157 checker[method_name] = {
160 requirement.min_arg_count, arg_info.max_positional_args)};
161 }
162 }
163
164#undef SET_CASE_AND_CONTINUE
165
166 return checker;
167 }
168
169 template <typename... Args>
170 llvm::Expected<StructuredData::GenericSP>
171 CreatePluginObject(const ScriptedMetadata &scripted_metadata,
172 StructuredData::Generic *script_obj, Args... args) {
173 using namespace python;
175
176 Log *log = GetLog(LLDBLog::Script);
177 auto create_error = [](llvm::StringLiteral format, auto &&...ts) {
178 return llvm::createStringError(
179 llvm::formatv(format.data(), std::forward<decltype(ts)>(ts)...)
180 .str());
181 };
182
183 m_scripted_metadata = scripted_metadata;
184 llvm::StringRef class_name = scripted_metadata.GetClassName();
185 bool has_class_name = !class_name.empty();
186 bool has_interpreter_dict =
187 !(llvm::StringRef(m_interpreter.GetDictionaryName()).empty());
188 if (!has_class_name && !has_interpreter_dict && !script_obj) {
189 if (!has_class_name)
190 return create_error("Missing script class name.");
191 else if (!has_interpreter_dict)
192 return create_error("Invalid script interpreter dictionary.");
193 else
194 return create_error("Missing scripting object.");
195 }
196
199
200 PythonObject result = {};
201
202 if (script_obj) {
203 result = PythonObject(PyRefType::Borrowed,
204 static_cast<PyObject *>(script_obj->GetValue()));
205 } else {
206 auto dict =
207 PythonModule::MainModule().ResolveName<python::PythonDictionary>(
208 m_interpreter.GetDictionaryName());
209 if (!dict.IsAllocated())
210 return create_error("Could not find interpreter dictionary: {0}",
211 m_interpreter.GetDictionaryName());
212
213 auto init =
214 PythonObject::ResolveNameWithDictionary<python::PythonCallable>(
215 class_name, dict);
216 if (!init.IsAllocated())
217 return create_error("Could not find script class: {0}",
218 class_name.data());
219
220 std::tuple<Args...> original_args = std::forward_as_tuple(args...);
221 auto transformed_args = TransformArgs(original_args);
222
223 std::string error_string;
224 llvm::Expected<PythonCallable::ArgInfo> arg_info = init.GetArgInfo();
225 if (!arg_info) {
226 llvm::handleAllErrors(
227 arg_info.takeError(),
228 [&](PythonException &E) { error_string.append(E.ReadBacktrace()); },
229 [&](const llvm::ErrorInfoBase &E) {
230 error_string.append(E.message());
231 });
232 return llvm::createStringError(llvm::inconvertibleErrorCode(),
233 error_string);
234 }
235
236 llvm::Expected<PythonObject> expected_return_object =
237 create_error("Resulting object is not initialized.");
238
239 // This relax the requirement on the number of argument for
240 // initializing scripting extension if the size of the interface
241 // parameter pack contains 1 less element than the extension maximum
242 // number of positional arguments for this initializer.
243 //
244 // This addresses the cases where the embedded interpreter session
245 // dictionary is passed to the extension initializer which is not used
246 // most of the time.
247 // Note, though none of our API's suggest defining the interfaces with
248 // varargs, we have some extant clients that were doing that. To keep
249 // from breaking them, we just say putting a varargs in these signatures
250 // turns off argument checking.
251 size_t num_args = sizeof...(Args);
252 if (arg_info->max_positional_args != PythonCallable::ArgInfo::UNBOUNDED &&
253 num_args != arg_info->max_positional_args) {
254 if (num_args != arg_info->max_positional_args - 1)
255 return create_error("Passed arguments ({0}) doesn't match the number "
256 "of expected arguments ({1}).",
257 num_args, arg_info->max_positional_args);
258
259 std::apply(
260 [&init, &expected_return_object](auto &&...args) {
261 llvm::consumeError(expected_return_object.takeError());
262 expected_return_object = init(args...);
263 },
264 std::tuple_cat(transformed_args, std::make_tuple(dict)));
265 } else {
266 std::apply(
267 [&init, &expected_return_object](auto &&...args) {
268 llvm::consumeError(expected_return_object.takeError());
269 expected_return_object = init(args...);
270 },
271 transformed_args);
272 }
273
274 if (!expected_return_object)
275 return expected_return_object.takeError();
276 result = expected_return_object.get();
277 }
278
279 if (!result.IsValid())
280 return create_error("Resulting object is not a valid Python Object.");
281 if (!result.HasAttribute("__class__"))
282 return create_error("Resulting object doesn't have '__class__' member.");
283
284 PythonObject obj_class = result.GetAttributeValue("__class__");
285 if (!obj_class.IsValid())
286 return create_error("Resulting class object is not a valid.");
287 if (!obj_class.HasAttribute("__name__"))
288 return create_error(
289 "Resulting object class doesn't have '__name__' member.");
290 PythonString obj_class_name =
291 obj_class.GetAttributeValue("__name__").AsType<PythonString>();
292
293 PythonObject object_class_mapping_proxy =
294 obj_class.GetAttributeValue("__dict__");
295 if (!obj_class.HasAttribute("__dict__"))
296 return create_error(
297 "Resulting object class doesn't have '__dict__' member.");
298
299 PythonCallable dict_converter = PythonModule::BuiltinsModule()
300 .ResolveName("dict")
301 .AsType<PythonCallable>();
302 if (!dict_converter.IsAllocated())
303 return create_error(
304 "Python 'builtins' module doesn't have 'dict' class.");
305
306 PythonDictionary object_class_dict =
307 dict_converter(object_class_mapping_proxy).AsType<PythonDictionary>();
308 if (!object_class_dict.IsAllocated())
309 return create_error("Coudn't create dictionary from resulting object "
310 "class mapping proxy object.");
311
312 auto checker_or_err = CheckAbstractMethodImplementation(object_class_dict);
313 if (!checker_or_err)
314 return checker_or_err.takeError();
315
316 llvm::Error abstract_method_errors = llvm::Error::success();
317 for (const auto &method_checker : *checker_or_err)
318 switch (method_checker.second.checker_case) {
320 abstract_method_errors = llvm::joinErrors(
321 std::move(abstract_method_errors),
322 std::move(create_error("Abstract method {0}.{1} not implemented.",
323 obj_class_name.GetString(),
324 method_checker.first)));
325 break;
327 abstract_method_errors = llvm::joinErrors(
328 std::move(abstract_method_errors),
329 std::move(create_error("Abstract method {0}.{1} not allocated.",
330 obj_class_name.GetString(),
331 method_checker.first)));
332 break;
334 abstract_method_errors = llvm::joinErrors(
335 std::move(abstract_method_errors),
336 std::move(create_error("Abstract method {0}.{1} not callable.",
337 obj_class_name.GetString(),
338 method_checker.first)));
339 break;
341 abstract_method_errors = llvm::joinErrors(
342 std::move(abstract_method_errors),
343 std::move(create_error(
344 "Abstract method {0}.{1} has unknown argument count.",
345 obj_class_name.GetString(), method_checker.first)));
346 break;
348 auto &payload_variant = method_checker.second.payload;
349 if (!std::holds_alternative<
351 payload_variant)) {
352 abstract_method_errors = llvm::joinErrors(
353 std::move(abstract_method_errors),
354 std::move(create_error(
355 "Abstract method {0}.{1} has unexpected argument count.",
356 obj_class_name.GetString(), method_checker.first)));
357 } else {
358 auto payload = std::get<
360 payload_variant);
361 abstract_method_errors = llvm::joinErrors(
362 std::move(abstract_method_errors),
363 std::move(
364 create_error("Abstract method {0}.{1} has unexpected "
365 "argument count (expected {2} but has {3}).",
366 obj_class_name.GetString(), method_checker.first,
367 payload.required_argument_count,
368 payload.actual_argument_count)));
369 }
370 } break;
372 LLDB_LOG(log, "Abstract method {0}.{1} implemented & valid.",
373 obj_class_name.GetString(), method_checker.first);
374 break;
375 }
376
377 if (abstract_method_errors) {
378 Status error = Status::FromError(std::move(abstract_method_errors));
379 LLDB_LOG(log, "Abstract method error in {0}:\n{1}", class_name,
380 error.AsCString());
381 return error.ToError();
382 }
383
385 new StructuredPythonObject(std::move(result)));
387 }
388
389 /// Call a static method on a Python class without creating an instance.
390 ///
391 /// This method resolves a Python class by name and calls a static method
392 /// on it, returning the result. This is useful for calling class-level
393 /// methods that don't require an instance.
394 ///
395 /// \param class_name The fully-qualified name of the Python class.
396 /// \param method_name The name of the static method to call.
397 /// \param error Output parameter to receive error information if the call
398 /// fails.
399 /// \param args Arguments to pass to the static method.
400 ///
401 /// \return The return value of the static method call, or an error value.
402 template <typename T = StructuredData::ObjectSP, typename... Args>
403 T CallStaticMethod(llvm::StringRef class_name, llvm::StringRef method_name,
404 Status &error, Args &&...args) {
405 using namespace python;
407
408 std::string caller_signature =
409 llvm::Twine(LLVM_PRETTY_FUNCTION + llvm::Twine(" (") +
410 llvm::Twine(class_name) + llvm::Twine(".") +
411 llvm::Twine(method_name) + llvm::Twine(")"))
412 .str();
413
414 if (class_name.empty())
415 return ErrorWithMessage<T>(caller_signature, "missing script class name",
416 error);
417
420
421 // Get the interpreter dictionary.
422 auto dict =
423 PythonModule::MainModule().ResolveName<python::PythonDictionary>(
424 m_interpreter.GetDictionaryName());
425 if (!dict.IsAllocated())
426 return ErrorWithMessage<T>(
427 caller_signature,
428 llvm::formatv("could not find interpreter dictionary: {0}",
429 m_interpreter.GetDictionaryName())
430 .str(),
431 error);
432
433 // Resolve the class.
434 auto class_obj =
435 PythonObject::ResolveNameWithDictionary<python::PythonCallable>(
436 class_name, dict);
437 if (!class_obj.IsAllocated())
438 return ErrorWithMessage<T>(
439 caller_signature,
440 llvm::formatv("could not find script class: {0}", class_name).str(),
441 error);
442
443 // Get the static method from the class.
444 if (!class_obj.HasAttribute(method_name))
445 return ErrorWithMessage<T>(
446 caller_signature,
447 llvm::formatv("class {0} does not have method {1}", class_name,
448 method_name)
449 .str(),
450 error);
451
452 PythonCallable method =
453 class_obj.GetAttributeValue(method_name).AsType<PythonCallable>();
454 if (!method.IsAllocated())
455 return ErrorWithMessage<T>(caller_signature,
456 llvm::formatv("method {0}.{1} is not callable",
457 class_name, method_name)
458 .str(),
459 error);
460
461 // Transform the arguments.
462 std::tuple<Args...> original_args = std::forward_as_tuple(args...);
463 auto transformed_args = TransformArgs(original_args);
464
465 // Call the static method.
466 llvm::Expected<PythonObject> expected_return_object =
467 llvm::createStringError("not initialized");
468 std::apply(
469 [&method, &expected_return_object](auto &&...args) {
470 llvm::consumeError(expected_return_object.takeError());
471 expected_return_object = method(args...);
472 },
473 transformed_args);
474
475 if (llvm::Error e = expected_return_object.takeError()) {
476 error = Status::FromError(std::move(e));
477 return ErrorWithMessage<T>(
478 caller_signature, "python static method could not be called", error);
479 }
480
481 PythonObject py_return = std::move(expected_return_object.get());
482
483 // Re-assign reference and pointer arguments if needed.
484 if (sizeof...(Args) > 0)
485 if (!ReassignPtrsOrRefsArgs(original_args, transformed_args))
486 return ErrorWithMessage<T>(
487 caller_signature,
488 "couldn't re-assign reference and pointer arguments", error);
489
490 // Extract value from Python object (handles unallocated case).
491 return ExtractValueFromPythonObject<T>(py_return, error);
492 }
493
494protected:
495 template <typename T = StructuredData::ObjectSP>
499
500 template <typename T = StructuredData::ObjectSP, typename... Args>
501 T Dispatch(llvm::StringRef method_name, Status &error, Args &&...args) {
502 using namespace python;
504
505 std::string caller_signature =
506 llvm::Twine(LLVM_PRETTY_FUNCTION + llvm::Twine(" (") +
507 llvm::Twine(method_name) + llvm::Twine(")"))
508 .str();
510 return ErrorWithMessage<T>(caller_signature, "python object ill-formed",
511 error);
512
515
516 PythonObject implementor(PyRefType::Borrowed,
517 (PyObject *)m_object_instance_sp->GetValue());
518
519 if (!implementor.IsAllocated())
520 return llvm::is_contained(GetAbstractMethods(), method_name)
521 ? ErrorWithMessage<T>(caller_signature,
522 "python implementor not allocated",
523 error)
524 : T{};
525
526 std::tuple<Args...> original_args = std::forward_as_tuple(args...);
527 auto transformed_args = TransformArgs(original_args);
528
529 llvm::Expected<PythonObject> expected_return_object =
530 llvm::createStringError("not initialized");
531 std::apply(
532 [&implementor, &method_name, &expected_return_object](auto &&...args) {
533 llvm::consumeError(expected_return_object.takeError());
534 expected_return_object =
535 implementor.CallMethod(method_name.data(), args...);
536 },
537 transformed_args);
538
539 if (llvm::Error e = expected_return_object.takeError()) {
540 error = Status::FromError(std::move(e));
541 return ErrorWithMessage<T>(caller_signature,
542 "python method could not be called", error);
543 }
544
545 PythonObject py_return = std::move(expected_return_object.get());
546
547 // Now that we called the python method with the transformed arguments,
548 // we need to iterate again over both the original and transformed
549 // parameter pack, and transform back the parameter that were passed in
550 // the original parameter pack as references or pointers.
551 if (sizeof...(Args) > 0)
552 if (!ReassignPtrsOrRefsArgs(original_args, transformed_args))
553 return ErrorWithMessage<T>(
554 caller_signature,
555 "couldn't re-assign reference and pointer arguments", error);
556
557 if (!py_return.IsAllocated())
558 return {};
559 return ExtractValueFromPythonObject<T>(py_return, error);
560 }
561
562 template <typename... Args>
563 Status GetStatusFromMethod(llvm::StringRef method_name, Args &&...args) {
565 Dispatch<Status>(method_name, error, std::forward<Args>(args)...);
566
567 return error;
568 }
569
570 template <typename T> T Transform(T object) {
571 // No Transformation for generic usage
572 return {object};
573 }
574
576 // Boolean arguments need to be turned into python objects.
577 return python::PythonBoolean(arg);
578 }
579
583
585 return python::SWIGBridge::ToSWIGWrapper(std::move(arg));
586 }
587
591
592 template <typename T, typename = std::enable_if_t<
593 std::is_base_of_v<StructuredData::Object, T>>>
594 python::PythonObject Transform(std::shared_ptr<T> arg) {
595 return Transform(StructuredDataImpl(arg));
596 }
597
601
605
609
613
617
621
625
629
633
637
641
645
649
653
657
661
665
666 template <typename T, typename U>
667 void ReverseTransform(T &original_arg, U transformed_arg, Status &error) {
668 // If U is not a PythonObject, don't touch it!
669 }
670
671 template <typename T>
672 void ReverseTransform(T &original_arg, python::PythonObject transformed_arg,
673 Status &error) {
674 original_arg = ExtractValueFromPythonObject<T>(transformed_arg, error);
675 }
676
677 void ReverseTransform(bool &original_arg,
678 python::PythonObject transformed_arg, Status &error) {
680 python::PyRefType::Borrowed, transformed_arg.get());
681 if (boolean_arg.IsValid())
682 original_arg = boolean_arg.GetValue();
683 else
685 "{}: Invalid boolean argument.", LLVM_PRETTY_FUNCTION);
686 }
687
688 template <std::size_t... I, typename... Args>
689 auto TransformTuple(const std::tuple<Args...> &args,
690 std::index_sequence<I...>) {
691 return std::make_tuple(Transform(std::get<I>(args))...);
692 }
693
694 // This will iterate over the Dispatch parameter pack and replace in-place
695 // every `lldb_private` argument that has a SB counterpart.
696 template <typename... Args>
697 auto TransformArgs(const std::tuple<Args...> &args) {
698 return TransformTuple(args, std::make_index_sequence<sizeof...(Args)>());
699 }
700
701 template <typename T, typename U>
702 void TransformBack(T &original_arg, U transformed_arg, Status &error) {
703 ReverseTransform(original_arg, transformed_arg, error);
704 }
705
706 template <std::size_t... I, typename... Ts, typename... Us>
707 bool ReassignPtrsOrRefsArgs(std::tuple<Ts...> &original_args,
708 std::tuple<Us...> &transformed_args,
709 std::index_sequence<I...>) {
711 (TransformBack(std::get<I>(original_args), std::get<I>(transformed_args),
712 error),
713 ...);
714 return error.Success();
715 }
716
717 template <typename... Ts, typename... Us>
718 bool ReassignPtrsOrRefsArgs(std::tuple<Ts...> &original_args,
719 std::tuple<Us...> &transformed_args) {
720 if (sizeof...(Ts) != sizeof...(Us))
721 return false;
722
723 return ReassignPtrsOrRefsArgs(original_args, transformed_args,
724 std::make_index_sequence<sizeof...(Ts)>());
725 }
726
727 template <typename T, typename... Args>
728 void FormatArgs(std::string &fmt, T arg, Args... args) const {
729 FormatArgs(fmt, arg);
730 FormatArgs(fmt, args...);
731 }
732
733 template <typename T> void FormatArgs(std::string &fmt, T arg) const {
735 }
736
737 void FormatArgs(std::string &fmt) const {}
738
739 // The lifetime is managed by the ScriptInterpreter
741};
742
743template <>
747
748template <>
752
753template <>
756
757template <>
760
761template <>
765
766template <>
770
771template <>
775
776template <>
780
781template <>
785
786template <>
790
791template <>
794
795template <>
798
799template <>
803
804template <>
805std::optional<MemoryRegionInfo>
807 std::optional<MemoryRegionInfo>>(python::PythonObject &p, Status &error);
808
809template <>
813
814template <>
818
819template <>
823
824template <>
828
829template <>
833
834template <>
838
839} // namespace lldb_private
840
841#endif // LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPYTHONINTERFACE_H
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:364
ScriptInterpreterPythonImpl::Locker Locker
#define SET_CASE_AND_CONTINUE(method_name, case)
A command line argument class.
Definition Args.h:33
A file utility class.
Definition FileSpec.h:57
static Ret ErrorWithMessage(llvm::StringRef caller_name, llvm::StringRef error_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
StructuredData::GenericSP m_object_instance_sp
llvm::StringRef GetClassName() const
python::PythonObject Transform(lldb::StackFrameListSP arg)
python::PythonObject Transform(lldb::ThreadPlanSP arg)
Status GetStatusFromMethod(llvm::StringRef method_name, Args &&...args)
python::PythonObject Transform(lldb::ProcessSP arg)
void TransformBack(T &original_arg, U transformed_arg, Status &error)
ScriptInterpreterPythonImpl & m_interpreter
python::PythonObject Transform(Event *arg)
auto TransformArgs(const std::tuple< Args... > &args)
python::PythonObject Transform(lldb::ExecutionContextRefSP arg)
python::PythonObject Transform(lldb::ThreadSP arg)
llvm::Expected< std::map< llvm::StringLiteral, AbstractMethodCheckerPayload > > CheckAbstractMethodImplementation(const python::PythonDictionary &class_dict) const
python::PythonObject Transform(const StructuredDataImpl &arg)
T ExtractValueFromPythonObject(python::PythonObject &p, Status &error)
~ScriptedPythonInterface() override=default
llvm::Expected< FileSpec > GetScriptedModulePath() override
python::PythonObject Transform(lldb::DescriptionLevel arg)
python::PythonObject Transform(const Status &arg)
python::PythonObject Transform(const SymbolContext &arg)
void ReverseTransform(T &original_arg, python::PythonObject transformed_arg, Status &error)
void FormatArgs(std::string &fmt, T arg, Args... args) const
python::PythonObject Transform(lldb::BreakpointSP arg)
void FormatArgs(std::string &fmt, T arg) const
ScriptedPythonInterface(ScriptInterpreterPythonImpl &interpreter)
void ReverseTransform(T &original_arg, U transformed_arg, Status &error)
T CallStaticMethod(llvm::StringRef class_name, llvm::StringRef method_name, Status &error, Args &&...args)
Call a static method on a Python class without creating an instance.
T Dispatch(llvm::StringRef method_name, Status &error, Args &&...args)
python::PythonObject Transform(lldb::BreakpointLocationSP arg)
python::PythonObject Transform(std::shared_ptr< T > arg)
bool ReassignPtrsOrRefsArgs(std::tuple< Ts... > &original_args, std::tuple< Us... > &transformed_args)
python::PythonObject Transform(lldb::StreamSP arg)
python::PythonObject Transform(Status &&arg)
python::PythonObject Transform(lldb::DataExtractorSP arg)
python::PythonObject Transform(lldb::StackFrameSP arg)
bool ReassignPtrsOrRefsArgs(std::tuple< Ts... > &original_args, std::tuple< Us... > &transformed_args, std::index_sequence< I... >)
python::PythonObject Transform(lldb::ProcessLaunchInfoSP arg)
llvm::Expected< StructuredData::GenericSP > CreatePluginObject(const ScriptedMetadata &scripted_metadata, StructuredData::Generic *script_obj, Args... args)
python::PythonObject Transform(lldb::TargetSP arg)
auto TransformTuple(const std::tuple< Args... > &args, std::index_sequence< I... >)
void ReverseTransform(bool &original_arg, python::PythonObject transformed_arg, Status &error)
python::PythonObject Transform(lldb::ValueObjectSP arg)
python::PythonObject Transform(lldb::ProcessAttachInfoSP arg)
An error handling class.
Definition Status.h:118
Status Clone() const
Don't call this function in new code.
Definition Status.h:174
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
Definition Status.h:151
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
Definition Status.cpp:136
std::shared_ptr< Generic > GenericSP
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
std::shared_ptr< Array > ArraySP
Defines a symbol context baton that can be handed other debug core functions.
llvm::Expected< PythonObject > GetItem(const PythonObject &key) const
bool HasKey(const llvm::Twine &key) const
StructuredData::ObjectSP CreateStructuredObject() const
static PythonObject ToSWIGWrapper(std::unique_ptr< lldb::SBValue > value_sb)
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:327
std::shared_ptr< lldb_private::ThreadPlan > ThreadPlanSP
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::BreakpointLocation > BreakpointLocationSP
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::shared_ptr< lldb_private::ProcessAttachInfo > ProcessAttachInfoSP
std::shared_ptr< lldb_private::Stream > StreamSP
std::shared_ptr< lldb_private::Breakpoint > BreakpointSP
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::ValueObjectList > ValueObjectListSP
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::DataExtractor > DataExtractorSP
std::shared_ptr< lldb_private::ProcessLaunchInfo > ProcessLaunchInfoSP
std::shared_ptr< lldb_private::StackFrameList > StackFrameListSP
std::shared_ptr< lldb_private::ExecutionContextRef > ExecutionContextRefSP
std::variant< std::monostate, InvalidArgumentCountPayload > payload