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