1*35653324SMed Ismail Bennani //===-- ScriptedThreadPlanPythonInterface.cpp -----------------------------===//
2*35653324SMed Ismail Bennani //
3*35653324SMed Ismail Bennani // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*35653324SMed Ismail Bennani // See https://llvm.org/LICENSE.txt for license information.
5*35653324SMed Ismail Bennani // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*35653324SMed Ismail Bennani //
7*35653324SMed Ismail Bennani //===----------------------------------------------------------------------===//
8*35653324SMed Ismail Bennani 
9*35653324SMed Ismail Bennani #include "lldb/Core/PluginManager.h"
10*35653324SMed Ismail Bennani #include "lldb/Host/Config.h"
11*35653324SMed Ismail Bennani #include "lldb/Utility/Log.h"
12*35653324SMed Ismail Bennani #include "lldb/lldb-enumerations.h"
13*35653324SMed Ismail Bennani 
14*35653324SMed Ismail Bennani #if LLDB_ENABLE_PYTHON
15*35653324SMed Ismail Bennani 
16*35653324SMed Ismail Bennani // clang-format off
17*35653324SMed Ismail Bennani // LLDB Python header must be included first
18*35653324SMed Ismail Bennani #include "../lldb-python.h"
19*35653324SMed Ismail Bennani //clang-format on
20*35653324SMed Ismail Bennani 
21*35653324SMed Ismail Bennani #include "../SWIGPythonBridge.h"
22*35653324SMed Ismail Bennani #include "../ScriptInterpreterPythonImpl.h"
23*35653324SMed Ismail Bennani #include "ScriptedThreadPlanPythonInterface.h"
24*35653324SMed Ismail Bennani 
25*35653324SMed Ismail Bennani using namespace lldb;
26*35653324SMed Ismail Bennani using namespace lldb_private;
27*35653324SMed Ismail Bennani using namespace lldb_private::python;
28*35653324SMed Ismail Bennani 
29*35653324SMed Ismail Bennani ScriptedThreadPlanPythonInterface::ScriptedThreadPlanPythonInterface(
30*35653324SMed Ismail Bennani     ScriptInterpreterPythonImpl &interpreter)
31*35653324SMed Ismail Bennani     : ScriptedThreadPlanInterface(), ScriptedPythonInterface(interpreter) {}
32*35653324SMed Ismail Bennani 
33*35653324SMed Ismail Bennani llvm::Expected<StructuredData::GenericSP>
34*35653324SMed Ismail Bennani ScriptedThreadPlanPythonInterface::CreatePluginObject(
35*35653324SMed Ismail Bennani     const llvm::StringRef class_name, lldb::ThreadPlanSP thread_plan_sp,
36*35653324SMed Ismail Bennani     const StructuredDataImpl &args_sp) {
37*35653324SMed Ismail Bennani   return ScriptedPythonInterface::CreatePluginObject(class_name, nullptr,
38*35653324SMed Ismail Bennani                                                      thread_plan_sp, args_sp);
39*35653324SMed Ismail Bennani }
40*35653324SMed Ismail Bennani 
41*35653324SMed Ismail Bennani llvm::Expected<bool>
42*35653324SMed Ismail Bennani ScriptedThreadPlanPythonInterface::ExplainsStop(Event *event) {
43*35653324SMed Ismail Bennani   Status error;
44*35653324SMed Ismail Bennani   StructuredData::ObjectSP obj = Dispatch("explains_stop", error, event);
45*35653324SMed Ismail Bennani 
46*35653324SMed Ismail Bennani   if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
47*35653324SMed Ismail Bennani                                                     error)) {
48*35653324SMed Ismail Bennani     if (!obj)
49*35653324SMed Ismail Bennani       return false;
50*35653324SMed Ismail Bennani     return error.ToError();
51*35653324SMed Ismail Bennani   }
52*35653324SMed Ismail Bennani 
53*35653324SMed Ismail Bennani   return obj->GetBooleanValue();
54*35653324SMed Ismail Bennani }
55*35653324SMed Ismail Bennani 
56*35653324SMed Ismail Bennani llvm::Expected<bool>
57*35653324SMed Ismail Bennani ScriptedThreadPlanPythonInterface::ShouldStop(Event *event) {
58*35653324SMed Ismail Bennani   Status error;
59*35653324SMed Ismail Bennani   StructuredData::ObjectSP obj = Dispatch("should_stop", error, event);
60*35653324SMed Ismail Bennani 
61*35653324SMed Ismail Bennani   if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
62*35653324SMed Ismail Bennani                                                     error)) {
63*35653324SMed Ismail Bennani     if (!obj)
64*35653324SMed Ismail Bennani       return false;
65*35653324SMed Ismail Bennani     return error.ToError();
66*35653324SMed Ismail Bennani   }
67*35653324SMed Ismail Bennani 
68*35653324SMed Ismail Bennani   return obj->GetBooleanValue();
69*35653324SMed Ismail Bennani }
70*35653324SMed Ismail Bennani 
71*35653324SMed Ismail Bennani llvm::Expected<bool> ScriptedThreadPlanPythonInterface::IsStale() {
72*35653324SMed Ismail Bennani   Status error;
73*35653324SMed Ismail Bennani   StructuredData::ObjectSP obj = Dispatch("is_stale", error);
74*35653324SMed Ismail Bennani 
75*35653324SMed Ismail Bennani   if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
76*35653324SMed Ismail Bennani                                                     error)) {
77*35653324SMed Ismail Bennani     if (!obj)
78*35653324SMed Ismail Bennani       return false;
79*35653324SMed Ismail Bennani     return error.ToError();
80*35653324SMed Ismail Bennani   }
81*35653324SMed Ismail Bennani 
82*35653324SMed Ismail Bennani   return obj->GetBooleanValue();
83*35653324SMed Ismail Bennani }
84*35653324SMed Ismail Bennani 
85*35653324SMed Ismail Bennani lldb::StateType ScriptedThreadPlanPythonInterface::GetRunState() {
86*35653324SMed Ismail Bennani   Status error;
87*35653324SMed Ismail Bennani   StructuredData::ObjectSP obj = Dispatch("should_step", error);
88*35653324SMed Ismail Bennani 
89*35653324SMed Ismail Bennani   if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
90*35653324SMed Ismail Bennani                                                     error))
91*35653324SMed Ismail Bennani     return lldb::eStateStepping;
92*35653324SMed Ismail Bennani 
93*35653324SMed Ismail Bennani   return static_cast<lldb::StateType>(obj->GetUnsignedIntegerValue(
94*35653324SMed Ismail Bennani       static_cast<uint32_t>(lldb::eStateStepping)));
95*35653324SMed Ismail Bennani }
96*35653324SMed Ismail Bennani 
97*35653324SMed Ismail Bennani llvm::Error
98*35653324SMed Ismail Bennani ScriptedThreadPlanPythonInterface::GetStopDescription(lldb::StreamSP &stream) {
99*35653324SMed Ismail Bennani   Status error;
100*35653324SMed Ismail Bennani   Dispatch("stop_description", error, stream);
101*35653324SMed Ismail Bennani 
102*35653324SMed Ismail Bennani   if (error.Fail())
103*35653324SMed Ismail Bennani     return error.ToError();
104*35653324SMed Ismail Bennani 
105*35653324SMed Ismail Bennani   return llvm::Error::success();
106*35653324SMed Ismail Bennani }
107*35653324SMed Ismail Bennani 
108*35653324SMed Ismail Bennani void ScriptedThreadPlanPythonInterface::Initialize() {
109*35653324SMed Ismail Bennani   const std::vector<llvm::StringRef> ci_usages = {
110*35653324SMed Ismail Bennani       "thread step-scripted -C <script-name> [-k key -v value ...]"};
111*35653324SMed Ismail Bennani   const std::vector<llvm::StringRef> api_usages = {
112*35653324SMed Ismail Bennani       "SBThread.StepUsingScriptedThreadPlan"};
113*35653324SMed Ismail Bennani   PluginManager::RegisterPlugin(
114*35653324SMed Ismail Bennani       GetPluginNameStatic(),
115*35653324SMed Ismail Bennani       llvm::StringRef("Alter thread stepping logic and stop reason"),
116*35653324SMed Ismail Bennani       CreateInstance, eScriptLanguagePython, {ci_usages, api_usages});
117*35653324SMed Ismail Bennani }
118*35653324SMed Ismail Bennani 
119*35653324SMed Ismail Bennani void ScriptedThreadPlanPythonInterface::Terminate() {
120*35653324SMed Ismail Bennani   PluginManager::UnregisterPlugin(CreateInstance);
121*35653324SMed Ismail Bennani }
122*35653324SMed Ismail Bennani 
123*35653324SMed Ismail Bennani #endif
124