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