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/Utility/Logging.h"
12 #include "lldb/lldb-enumerations.h"
13 
14 #if LLDB_ENABLE_PYTHON
15 
16 // LLDB Python header must be included first
17 #include "lldb-python.h"
18 
19 #include "SWIGPythonBridge.h"
20 #include "ScriptInterpreterPythonImpl.h"
21 #include "ScriptedThreadPythonInterface.h"
22 
23 using namespace lldb;
24 using namespace lldb_private;
25 using namespace lldb_private::python;
26 using Locker = ScriptInterpreterPythonImpl::Locker;
27 
28 ScriptedThreadPythonInterface::ScriptedThreadPythonInterface(
29     ScriptInterpreterPythonImpl &interpreter)
30     : ScriptedThreadInterface(), ScriptedPythonInterface(interpreter) {}
31 
32 StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject(
33     const llvm::StringRef class_name, ExecutionContext &exe_ctx,
34     StructuredData::DictionarySP args_sp) {
35 
36   if (class_name.empty())
37     return {};
38 
39   ProcessSP process_sp = exe_ctx.GetProcessSP();
40   StructuredDataImpl *args_impl = nullptr;
41   if (args_sp) {
42     args_impl = new StructuredDataImpl();
43     args_impl->SetObjectSP(args_sp);
44   }
45   std::string error_string;
46 
47   Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
48                  Locker::FreeLock);
49 
50   void *ret_val = LLDBSwigPythonCreateScriptedThread(
51       class_name.str().c_str(), m_interpreter.GetDictionaryName(), process_sp,
52       args_impl, error_string);
53 
54   if (!ret_val)
55     return {};
56 
57   m_object_instance_sp =
58       StructuredData::GenericSP(new StructuredPythonObject(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   return nullptr;
116 }
117 
118 StructuredData::DictionarySP ScriptedThreadPythonInterface::GetRegisterInfo() {
119   Status error;
120   StructuredData::DictionarySP dict =
121       Dispatch<StructuredData::DictionarySP>("get_register_info", error);
122 
123   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
124     return {};
125 
126   return dict;
127 }
128 
129 llvm::Optional<std::string>
130 ScriptedThreadPythonInterface::GetRegisterContext() {
131   Status error;
132   StructuredData::ObjectSP obj = Dispatch("get_register_context", error);
133 
134   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
135     return {};
136 
137   return obj->GetAsString()->GetValue().str();
138 }
139 
140 #endif
141