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