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 
22 using namespace lldb;
23 using namespace lldb_private;
24 using namespace lldb_private::python;
25 using Locker = ScriptInterpreterPythonImpl::Locker;
26 
27 ScriptedThreadPythonInterface::ScriptedThreadPythonInterface(
28     ScriptInterpreterPythonImpl &interpreter)
29     : ScriptedThreadInterface(), ScriptedPythonInterface(interpreter) {}
30 
31 StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject(
32     const llvm::StringRef class_name, ExecutionContext &exe_ctx,
33     StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
34   if (class_name.empty() && !script_obj)
35     return {};
36 
37   ProcessSP process_sp = exe_ctx.GetProcessSP();
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     ret_val = LLDBSwigPythonCreateScriptedThread(
48         class_name.str().c_str(), m_interpreter.GetDictionaryName(), process_sp,
49         args_impl, error_string);
50   else
51     ret_val = PythonObject(PyRefType::Borrowed,
52                            static_cast<PyObject *>(script_obj->GetValue()));
53 
54   if (!ret_val)
55     return {};
56 
57   m_object_instance_sp =
58       StructuredData::GenericSP(new StructuredPythonObject(std::move(ret_val)));
59 
60   return m_object_instance_sp;
61 }
62 
63 lldb::tid_t ScriptedThreadPythonInterface::GetThreadID() {
64   Status error;
65   StructuredData::ObjectSP obj = Dispatch("get_thread_id", error);
66 
67   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
68     return LLDB_INVALID_THREAD_ID;
69 
70   return obj->GetIntegerValue(LLDB_INVALID_THREAD_ID);
71 }
72 
73 llvm::Optional<std::string> ScriptedThreadPythonInterface::GetName() {
74   Status error;
75   StructuredData::ObjectSP obj = Dispatch("get_name", error);
76 
77   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
78     return {};
79 
80   return obj->GetStringValue().str();
81 }
82 
83 lldb::StateType ScriptedThreadPythonInterface::GetState() {
84   Status error;
85   StructuredData::ObjectSP obj = Dispatch("get_state", error);
86 
87   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
88     return eStateInvalid;
89 
90   return static_cast<StateType>(obj->GetIntegerValue(eStateInvalid));
91 }
92 
93 llvm::Optional<std::string> ScriptedThreadPythonInterface::GetQueue() {
94   Status error;
95   StructuredData::ObjectSP obj = Dispatch("get_queue", error);
96 
97   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
98     return {};
99 
100   return obj->GetStringValue().str();
101 }
102 
103 StructuredData::DictionarySP ScriptedThreadPythonInterface::GetStopReason() {
104   Status error;
105   StructuredData::DictionarySP dict =
106       Dispatch<StructuredData::DictionarySP>("get_stop_reason", error);
107 
108   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
109     return {};
110 
111   return dict;
112 }
113 
114 StructuredData::ArraySP ScriptedThreadPythonInterface::GetStackFrames() {
115   Status error;
116   StructuredData::ArraySP arr =
117       Dispatch<StructuredData::ArraySP>("get_stackframes", error);
118 
119   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr, error))
120     return {};
121 
122   return arr;
123 }
124 
125 StructuredData::DictionarySP ScriptedThreadPythonInterface::GetRegisterInfo() {
126   Status error;
127   StructuredData::DictionarySP dict =
128       Dispatch<StructuredData::DictionarySP>("get_register_info", error);
129 
130   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
131     return {};
132 
133   return dict;
134 }
135 
136 llvm::Optional<std::string>
137 ScriptedThreadPythonInterface::GetRegisterContext() {
138   Status error;
139   StructuredData::ObjectSP obj = Dispatch("get_register_context", error);
140 
141   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
142     return {};
143 
144   return obj->GetAsString()->GetValue().str();
145 }
146 
147 #endif
148