1 //===-- ScriptedThreadPythonInterface.cpp ---------------------------------===//
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 #include "lldb/Host/Config.h"
10 #include "lldb/Utility/Log.h"
11 #include "lldb/lldb-enumerations.h"
12
13 #if LLDB_ENABLE_PYTHON
14
15 // LLDB Python header must be included first
16 #include "lldb-python.h"
17
18 #include "SWIGPythonBridge.h"
19 #include "ScriptInterpreterPythonImpl.h"
20 #include "ScriptedThreadPythonInterface.h"
21 #include <optional>
22
23 using namespace lldb;
24 using namespace lldb_private;
25 using namespace lldb_private::python;
26 using Locker = ScriptInterpreterPythonImpl::Locker;
27
ScriptedThreadPythonInterface(ScriptInterpreterPythonImpl & interpreter)28 ScriptedThreadPythonInterface::ScriptedThreadPythonInterface(
29 ScriptInterpreterPythonImpl &interpreter)
30 : ScriptedThreadInterface(), ScriptedPythonInterface(interpreter) {}
31
CreatePluginObject(const llvm::StringRef class_name,ExecutionContext & exe_ctx,StructuredData::DictionarySP args_sp,StructuredData::Generic * script_obj)32 StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject(
33 const llvm::StringRef class_name, ExecutionContext &exe_ctx,
34 StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
35 if (class_name.empty() && !script_obj)
36 return {};
37
38 StructuredDataImpl args_impl(args_sp);
39 std::string error_string;
40
41 Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
42 Locker::FreeLock);
43
44 PythonObject ret_val;
45
46 if (!script_obj) {
47 lldb::ExecutionContextRefSP exe_ctx_ref_sp =
48 std::make_shared<ExecutionContextRef>(exe_ctx);
49 ret_val = LLDBSwigPythonCreateScriptedObject(
50 class_name.str().c_str(), m_interpreter.GetDictionaryName(),
51 exe_ctx_ref_sp, args_impl, error_string);
52 } else
53 ret_val = PythonObject(PyRefType::Borrowed,
54 static_cast<PyObject *>(script_obj->GetValue()));
55
56 if (!ret_val)
57 return {};
58
59 m_object_instance_sp =
60 StructuredData::GenericSP(new StructuredPythonObject(std::move(ret_val)));
61
62 return m_object_instance_sp;
63 }
64
GetThreadID()65 lldb::tid_t ScriptedThreadPythonInterface::GetThreadID() {
66 Status error;
67 StructuredData::ObjectSP obj = Dispatch("get_thread_id", error);
68
69 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
70 return LLDB_INVALID_THREAD_ID;
71
72 return obj->GetIntegerValue(LLDB_INVALID_THREAD_ID);
73 }
74
GetName()75 std::optional<std::string> ScriptedThreadPythonInterface::GetName() {
76 Status error;
77 StructuredData::ObjectSP obj = Dispatch("get_name", error);
78
79 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
80 return {};
81
82 return obj->GetStringValue().str();
83 }
84
GetState()85 lldb::StateType ScriptedThreadPythonInterface::GetState() {
86 Status error;
87 StructuredData::ObjectSP obj = Dispatch("get_state", error);
88
89 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
90 return eStateInvalid;
91
92 return static_cast<StateType>(obj->GetIntegerValue(eStateInvalid));
93 }
94
GetQueue()95 std::optional<std::string> ScriptedThreadPythonInterface::GetQueue() {
96 Status error;
97 StructuredData::ObjectSP obj = Dispatch("get_queue", error);
98
99 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
100 return {};
101
102 return obj->GetStringValue().str();
103 }
104
GetStopReason()105 StructuredData::DictionarySP ScriptedThreadPythonInterface::GetStopReason() {
106 Status error;
107 StructuredData::DictionarySP dict =
108 Dispatch<StructuredData::DictionarySP>("get_stop_reason", error);
109
110 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
111 return {};
112
113 return dict;
114 }
115
GetStackFrames()116 StructuredData::ArraySP ScriptedThreadPythonInterface::GetStackFrames() {
117 Status error;
118 StructuredData::ArraySP arr =
119 Dispatch<StructuredData::ArraySP>("get_stackframes", error);
120
121 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr, error))
122 return {};
123
124 return arr;
125 }
126
GetRegisterInfo()127 StructuredData::DictionarySP ScriptedThreadPythonInterface::GetRegisterInfo() {
128 Status error;
129 StructuredData::DictionarySP dict =
130 Dispatch<StructuredData::DictionarySP>("get_register_info", error);
131
132 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
133 return {};
134
135 return dict;
136 }
137
GetRegisterContext()138 std::optional<std::string> ScriptedThreadPythonInterface::GetRegisterContext() {
139 Status error;
140 StructuredData::ObjectSP obj = Dispatch("get_register_context", error);
141
142 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
143 return {};
144
145 return obj->GetAsString()->GetValue().str();
146 }
147
GetExtendedInfo()148 StructuredData::ArraySP ScriptedThreadPythonInterface::GetExtendedInfo() {
149 Status error;
150 StructuredData::ArraySP arr =
151 Dispatch<StructuredData::ArraySP>("get_extended_info", error);
152
153 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr, error))
154 return {};
155
156 return arr;
157 }
158
159 #endif
160