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, StructuredData::Generic *script_obj) {
35   if (class_name.empty() && !script_obj)
36     return {};
37 
38   ProcessSP process_sp = exe_ctx.GetProcessSP();
39   StructuredDataImpl args_impl(args_sp);
40   std::string error_string;
41 
42   Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
43                  Locker::FreeLock);
44 
45   PythonObject ret_val;
46 
47   if (!script_obj)
48     ret_val = LLDBSwigPythonCreateScriptedThread(
49         class_name.str().c_str(), m_interpreter.GetDictionaryName(), process_sp,
50         args_impl, error_string);
51   else
52     ret_val = PythonObject(PyRefType::Borrowed,
53                            static_cast<PyObject *>(script_obj->GetValue()));
54 
55   if (!ret_val)
56     return {};
57 
58   m_object_instance_sp =
59       StructuredData::GenericSP(new StructuredPythonObject(std::move(ret_val)));
60 
61   return m_object_instance_sp;
62 }
63 
64 lldb::tid_t ScriptedThreadPythonInterface::GetThreadID() {
65   Status error;
66   StructuredData::ObjectSP obj = Dispatch("get_thread_id", error);
67 
68   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
69     return LLDB_INVALID_THREAD_ID;
70 
71   return obj->GetIntegerValue(LLDB_INVALID_THREAD_ID);
72 }
73 
74 llvm::Optional<std::string> ScriptedThreadPythonInterface::GetName() {
75   Status error;
76   StructuredData::ObjectSP obj = Dispatch("get_name", error);
77 
78   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
79     return {};
80 
81   return obj->GetStringValue().str();
82 }
83 
84 lldb::StateType ScriptedThreadPythonInterface::GetState() {
85   Status error;
86   StructuredData::ObjectSP obj = Dispatch("get_state", error);
87 
88   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
89     return eStateInvalid;
90 
91   return static_cast<StateType>(obj->GetIntegerValue(eStateInvalid));
92 }
93 
94 llvm::Optional<std::string> ScriptedThreadPythonInterface::GetQueue() {
95   Status error;
96   StructuredData::ObjectSP obj = Dispatch("get_queue", error);
97 
98   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
99     return {};
100 
101   return obj->GetStringValue().str();
102 }
103 
104 StructuredData::DictionarySP ScriptedThreadPythonInterface::GetStopReason() {
105   Status error;
106   StructuredData::DictionarySP dict =
107       Dispatch<StructuredData::DictionarySP>("get_stop_reason", error);
108 
109   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
110     return {};
111 
112   return dict;
113 }
114 
115 StructuredData::ArraySP ScriptedThreadPythonInterface::GetStackFrames() {
116   return nullptr;
117 }
118 
119 StructuredData::DictionarySP ScriptedThreadPythonInterface::GetRegisterInfo() {
120   Status error;
121   StructuredData::DictionarySP dict =
122       Dispatch<StructuredData::DictionarySP>("get_register_info", error);
123 
124   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
125     return {};
126 
127   return dict;
128 }
129 
130 llvm::Optional<std::string>
131 ScriptedThreadPythonInterface::GetRegisterContext() {
132   Status error;
133   StructuredData::ObjectSP obj = Dispatch("get_register_context", error);
134 
135   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
136     return {};
137 
138   return obj->GetAsString()->GetValue().str();
139 }
140 
141 #endif
142