diff --git a/lldb/bindings/python/python-swigsafecast.swig b/lldb/bindings/python/python-swigsafecast.swig index 34f8c6f0ff8d35..d5ea5148727134 100644 --- a/lldb/bindings/python/python-swigsafecast.swig +++ b/lldb/bindings/python/python-swigsafecast.swig @@ -37,6 +37,10 @@ PythonObject SWIGBridge::ToSWIGWrapper(const Status& status) { return ToSWIGHelper(new lldb::SBError(status), SWIGTYPE_p_lldb__SBError); } +PythonObject SWIGBridge::ToSWIGWrapper(std::unique_ptr stream_sb) { + return ToSWIGHelper(stream_sb.release(), SWIGTYPE_p_lldb__SBStream); +} + PythonObject SWIGBridge::ToSWIGWrapper(std::unique_ptr data_sb) { return ToSWIGHelper(data_sb.release(), SWIGTYPE_p_lldb__SBStructuredData); } @@ -111,16 +115,9 @@ SWIGBridge::ToSWIGWrapper(CommandReturnObject &cmd_retobj) { SWIGTYPE_p_lldb__SBCommandReturnObject); } -PythonObject SWIGBridge::ToSWIGWrapper(const Stream *s) { - return ToSWIGHelper(new lldb::SBStream(), SWIGTYPE_p_lldb__SBStream); -} - -PythonObject SWIGBridge::ToSWIGWrapper(std::shared_ptr stream_sb) { - return ToSWIGHelper(stream_sb.get(), SWIGTYPE_p_lldb__SBStream); -} - -PythonObject SWIGBridge::ToSWIGWrapper(Event *event) { - return ToSWIGHelper(new lldb::SBEvent(event), SWIGTYPE_p_lldb__SBEvent); +ScopedPythonObject SWIGBridge::ToSWIGWrapper(Event *event) { + return ScopedPythonObject(new lldb::SBEvent(event), + SWIGTYPE_p_lldb__SBEvent); } PythonObject SWIGBridge::ToSWIGWrapper( diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig index 28ab58f8ce495c..1370afc885d43f 100644 --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -229,6 +229,133 @@ PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateCommandObject return pfunc(SWIGBridge::ToSWIGWrapper(std::move(debugger_sp)), dict); } +PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateScriptedThreadPlan( + const char *python_class_name, const char *session_dictionary_name, + const lldb_private::StructuredDataImpl &args_impl, + std::string &error_string, const lldb::ThreadPlanSP &thread_plan_sp) { + if (python_class_name == NULL || python_class_name[0] == '\0' || + !session_dictionary_name) + return PythonObject(); + + PyErr_Cleaner py_err_cleaner(true); + + auto dict = PythonModule::MainModule().ResolveName( + session_dictionary_name); + auto pfunc = PythonObject::ResolveNameWithDictionary( + python_class_name, dict); + + if (!pfunc.IsAllocated()) { + error_string.append("could not find script class: "); + error_string.append(python_class_name); + return PythonObject(); + } + + PythonObject tp_arg = SWIGBridge::ToSWIGWrapper(thread_plan_sp); + + llvm::Expected arg_info = pfunc.GetArgInfo(); + if (!arg_info) { + llvm::handleAllErrors( + arg_info.takeError(), + [&](PythonException &E) { error_string.append(E.ReadBacktrace()); }, + [&](const llvm::ErrorInfoBase &E) { + error_string.append(E.message()); + }); + return PythonObject(); + } + + PythonObject result = {}; + auto args_sb = std::unique_ptr(new lldb::SBStructuredData(args_impl)); + if (arg_info.get().max_positional_args == 2) { + if (args_sb->IsValid()) { + error_string.assign( + "args passed, but __init__ does not take an args dictionary"); + return PythonObject(); + } + result = pfunc(tp_arg, dict); + } else if (arg_info.get().max_positional_args >= 3) { + result = pfunc(tp_arg, SWIGBridge::ToSWIGWrapper(std::move(args_sb)), dict); + } else { + error_string.assign("wrong number of arguments in __init__, should be 2 or " + "3 (not including self)"); + return PythonObject(); + } + + // FIXME: At this point we should check that the class we found supports all + // the methods that we need. + + return result; +} + +bool lldb_private::python::SWIGBridge::LLDBSWIGPythonCallThreadPlan( + void *implementer, const char *method_name, lldb_private::Event *event, + bool &got_error) { + got_error = false; + + PyErr_Cleaner py_err_cleaner(false); + PythonObject self(PyRefType::Borrowed, static_cast(implementer)); + auto pfunc = self.ResolveName(method_name); + + if (!pfunc.IsAllocated()) + return false; + + PythonObject result; + if (event != nullptr) { + ScopedPythonObject event_arg = SWIGBridge::ToSWIGWrapper(event); + result = pfunc(event_arg.obj()); + } else + result = pfunc(); + + if (PyErr_Occurred()) { + got_error = true; + printf("Return value was neither false nor true for call to %s.\n", + method_name); + PyErr_Print(); + return false; + } + + if (result.get() == Py_True) + return true; + else if (result.get() == Py_False) + return false; + + // Somebody returned the wrong thing... + got_error = true; + printf("Wrong return value type for call to %s.\n", method_name); + return false; +} + +bool lldb_private::python::SWIGBridge::LLDBSWIGPythonCallThreadPlan( + void *implementer, const char *method_name, lldb_private::Stream *stream, + bool &got_error) { + got_error = false; + + PyErr_Cleaner py_err_cleaner(false); + PythonObject self(PyRefType::Borrowed, static_cast(implementer)); + auto pfunc = self.ResolveName(method_name); + + if (!pfunc.IsAllocated()) + return false; + + auto *sb_stream = new lldb::SBStream(); + PythonObject sb_stream_arg = + SWIGBridge::ToSWIGWrapper(std::unique_ptr(sb_stream)); + + PythonObject result; + result = pfunc(sb_stream_arg); + + if (PyErr_Occurred()) { + printf("Error occured for call to %s.\n", + method_name); + PyErr_Print(); + got_error = true; + return false; + } + if (stream) + stream->PutCString(sb_stream->GetData()); + return true; + +} + PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateScriptedBreakpointResolver( const char *python_class_name, const char *session_dictionary_name, const StructuredDataImpl &args_impl, @@ -373,8 +500,9 @@ bool lldb_private::python::SWIGBridge::LLDBSwigPythonStopHookCallHandleStop( if (!pfunc.IsAllocated()) return true; - std::shared_ptr sb_stream = std::make_shared(); - PythonObject sb_stream_arg = SWIGBridge::ToSWIGWrapper(sb_stream); + auto *sb_stream = new lldb::SBStream(); + PythonObject sb_stream_arg = + SWIGBridge::ToSWIGWrapper(std::unique_ptr(sb_stream)); PythonObject result = pfunc(SWIGBridge::ToSWIGWrapper(std::move(exc_ctx_sp)), sb_stream_arg); @@ -389,7 +517,6 @@ bool lldb_private::python::SWIGBridge::LLDBSwigPythonStopHookCallHandleStop( // makes an internally help StreamString which I can't interpose, so I // have to copy it over here. stream->PutCString(sb_stream->GetData()); - sb_stream_arg.release(); if (result.get() == Py_False) return false; @@ -626,30 +753,6 @@ void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBError(PyObject * data return sb_ptr; } -void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBEvent(PyObject * data) { - lldb::SBEvent *sb_ptr = nullptr; - - int valid_cast = - SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBEvent, 0); - - if (valid_cast == -1) - return NULL; - - return sb_ptr; -} - -void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBStream(PyObject * data) { - lldb::SBStream *sb_ptr = nullptr; - - int valid_cast = - SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBStream, 0); - - if (valid_cast == -1) - return NULL; - - return sb_ptr; -} - void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBValue(PyObject * data) { lldb::SBValue *sb_ptr = NULL; diff --git a/lldb/include/lldb/API/SBEvent.h b/lldb/include/lldb/API/SBEvent.h index 85b401ca8cc100..cc116766e85f4a 100644 --- a/lldb/include/lldb/API/SBEvent.h +++ b/lldb/include/lldb/API/SBEvent.h @@ -15,7 +15,6 @@ #include namespace lldb_private { -class ScriptInterpreter; namespace python { class SWIGBridge; } @@ -74,12 +73,11 @@ class LLDB_API SBEvent { friend class SBThread; friend class SBWatchpoint; - friend class lldb_private::ScriptInterpreter; friend class lldb_private::python::SWIGBridge; SBEvent(lldb::EventSP &event_sp); - SBEvent(lldb_private::Event *event); + SBEvent(lldb_private::Event *event_sp); lldb::EventSP &GetSP() const; diff --git a/lldb/include/lldb/API/SBStream.h b/lldb/include/lldb/API/SBStream.h index 2db379fe12f092..0e33f05b69916f 100644 --- a/lldb/include/lldb/API/SBStream.h +++ b/lldb/include/lldb/API/SBStream.h @@ -13,10 +13,6 @@ #include "lldb/API/SBDefines.h" -namespace lldb_private { -class ScriptInterpreter; -} // namespace lldb_private - namespace lldb { class LLDB_API SBStream { @@ -105,8 +101,6 @@ class LLDB_API SBStream { friend class SBValue; friend class SBWatchpoint; - friend class lldb_private::ScriptInterpreter; - lldb_private::Stream *operator->(); lldb_private::Stream *get(); diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h index 69504dbcda5dc8..9753a916243b7b 100644 --- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h +++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h @@ -10,6 +10,7 @@ #define LLDB_INTERPRETER_INTERFACES_SCRIPTEDINTERFACE_H #include "lldb/Core/StructuredDataImpl.h" +#include "lldb/Target/ExecutionContext.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/UnimplementedError.h" @@ -51,8 +52,7 @@ class ScriptedInterface { } template - static bool CheckStructuredDataObject(llvm::StringRef caller, T obj, - Status &error) { + bool CheckStructuredDataObject(llvm::StringRef caller, T obj, Status &error) { if (!obj) return ErrorWithMessage(caller, "Null Structured Data object", error); diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h deleted file mode 100644 index 9130f9412cb0bd..00000000000000 --- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h +++ /dev/null @@ -1,38 +0,0 @@ -//===-- ScriptedThreadPlanInterface.h ---------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_INTERPRETER_INTERFACES_SCRIPTEDTHREADPLANINTERFACE_H -#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDTHREADPLANINTERFACE_H - -#include "lldb/lldb-private.h" - -#include "ScriptedInterface.h" - -namespace lldb_private { -class ScriptedThreadPlanInterface : public ScriptedInterface { -public: - virtual llvm::Expected - CreatePluginObject(llvm::StringRef class_name, - lldb::ThreadPlanSP thread_plan_sp, - const StructuredDataImpl &args_sp) = 0; - - virtual llvm::Expected ExplainsStop(Event *event) { return true; } - - virtual llvm::Expected ShouldStop(Event *event) { return true; } - - virtual llvm::Expected IsStale() { return true; }; - - virtual lldb::StateType GetRunState() { return lldb::eStateStepping; } - - virtual llvm::Expected GetStopDescription(lldb_private::Stream *s) { - return true; - } -}; -} // namespace lldb_private - -#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDTHREADPLANINTERFACE_H diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h index e821a7db2c6748..932eaa8b8a4a28 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -13,10 +13,8 @@ #include "lldb/API/SBBreakpoint.h" #include "lldb/API/SBData.h" #include "lldb/API/SBError.h" -#include "lldb/API/SBEvent.h" #include "lldb/API/SBLaunchInfo.h" #include "lldb/API/SBMemoryRegionInfo.h" -#include "lldb/API/SBStream.h" #include "lldb/Breakpoint/BreakpointOptions.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Core/SearchFilter.h" @@ -252,6 +250,50 @@ class ScriptInterpreter : public PluginInterface { return lldb::ValueObjectListSP(); } + virtual StructuredData::ObjectSP + CreateScriptedThreadPlan(const char *class_name, + const StructuredDataImpl &args_data, + std::string &error_str, + lldb::ThreadPlanSP thread_plan_sp) { + return StructuredData::ObjectSP(); + } + + virtual bool + ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp, + Event *event, bool &script_error) { + script_error = true; + return true; + } + + virtual bool + ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp, + Event *event, bool &script_error) { + script_error = true; + return true; + } + + virtual bool + ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp, + bool &script_error) { + script_error = true; + return true; + } + + virtual lldb::StateType + ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, + bool &script_error) { + script_error = true; + return lldb::eStateStepping; + } + + virtual bool + ScriptedThreadPlanGetStopDescription(StructuredData::ObjectSP implementor_sp, + lldb_private::Stream *stream, + bool &script_error) { + script_error = true; + return false; + } + virtual StructuredData::GenericSP CreateScriptedBreakpointResolver(const char *class_name, const StructuredDataImpl &args_data, @@ -550,11 +592,6 @@ class ScriptInterpreter : public PluginInterface { return {}; } - virtual lldb::ScriptedThreadPlanInterfaceSP - CreateScriptedThreadPlanInterface() { - return {}; - } - virtual lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() { return {}; } @@ -573,10 +610,6 @@ class ScriptInterpreter : public PluginInterface { Status GetStatusFromSBError(const lldb::SBError &error) const; - Event *GetOpaqueTypeFromSBEvent(const lldb::SBEvent &event) const; - - Stream *GetOpaqueTypeFromSBStream(const lldb::SBStream &stream) const; - lldb::BreakpointSP GetOpaqueTypeFromSBBreakpoint(const lldb::SBBreakpoint &breakpoint) const; diff --git a/lldb/include/lldb/Target/ThreadPlanPython.h b/lldb/include/lldb/Target/ThreadPlanPython.h index da106faf951db1..64854d66b8f258 100644 --- a/lldb/include/lldb/Target/ThreadPlanPython.h +++ b/lldb/include/lldb/Target/ThreadPlanPython.h @@ -13,7 +13,6 @@ #include #include "lldb/Core/StructuredDataImpl.h" -#include "lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h" #include "lldb/Target/Process.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" @@ -71,7 +70,6 @@ class ThreadPlanPython : public ThreadPlan { StreamString m_stop_description; // Cache the stop description here bool m_did_push; bool m_stop_others; - lldb::ScriptedThreadPlanInterfaceSP m_interface; ThreadPlanPython(const ThreadPlanPython &) = delete; const ThreadPlanPython &operator=(const ThreadPlanPython &) = delete; diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index e2b24819bce96b..10ba921b9dac8c 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -187,7 +187,6 @@ class ScriptedMetadata; class ScriptedPlatformInterface; class ScriptedProcessInterface; class ScriptedThreadInterface; -class ScriptedThreadPlanInterface; class ScriptedSyntheticChildren; class SearchFilter; class Section; @@ -404,8 +403,6 @@ typedef std::unique_ptr ScriptedProcessInterfaceUP; typedef std::shared_ptr ScriptedThreadInterfaceSP; -typedef std::shared_ptr - ScriptedThreadPlanInterfaceSP; typedef std::shared_ptr SectionSP; typedef std::unique_ptr SectionListUP; typedef std::weak_ptr SectionWP; diff --git a/lldb/source/Interpreter/ScriptInterpreter.cpp b/lldb/source/Interpreter/ScriptInterpreter.cpp index 75b2a39a8d11b3..8dd499ce819a78 100644 --- a/lldb/source/Interpreter/ScriptInterpreter.cpp +++ b/lldb/source/Interpreter/ScriptInterpreter.cpp @@ -101,19 +101,6 @@ ScriptInterpreter::GetStatusFromSBError(const lldb::SBError &error) const { return Status(); } -Event * -ScriptInterpreter::GetOpaqueTypeFromSBEvent(const lldb::SBEvent &event) const { - return event.m_opaque_ptr; -} - -Stream *ScriptInterpreter::GetOpaqueTypeFromSBStream( - const lldb::SBStream &stream) const { - if (stream.m_opaque_up) - return const_cast(stream).m_opaque_up.get(); - - return nullptr; -} - std::optional ScriptInterpreter::GetOpaqueTypeFromSBMemoryRegionInfo( const lldb::SBMemoryRegionInfo &mem_region) const { diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt index c60e4bb503a371..b22abc49c92a9a 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt @@ -24,7 +24,6 @@ add_lldb_library(lldbPluginScriptInterpreterPythonInterfaces ScriptedPythonInterface.cpp ScriptedProcessPythonInterface.cpp ScriptedThreadPythonInterface.cpp - ScriptedThreadPlanPythonInterface.cpp ScriptedPlatformPythonInterface.cpp LINK_LIBS diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.cpp index 6e93bec80056ee..9ba4731032bd35 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.cpp @@ -20,8 +20,6 @@ #include "../ScriptInterpreterPythonImpl.h" #include "ScriptedPlatformPythonInterface.h" -#include "lldb/Target/ExecutionContext.h" - using namespace lldb; using namespace lldb_private; using namespace lldb_private::python; diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.cpp index 313c597ce48f3c..e86b34d6b930e4 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.cpp @@ -49,8 +49,7 @@ StructuredData::DictionarySP ScriptedProcessPythonInterface::GetCapabilities() { StructuredData::DictionarySP dict = Dispatch("get_capabilities", error); - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, - error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error)) return {}; return dict; @@ -91,8 +90,7 @@ StructuredData::DictionarySP ScriptedProcessPythonInterface::GetThreadsInfo() { StructuredData::DictionarySP dict = Dispatch("get_threads_info", error); - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, - error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error)) return {}; return dict; @@ -108,8 +106,7 @@ bool ScriptedProcessPythonInterface::CreateBreakpoint(lldb::addr_t addr, if (py_error.Fail()) error = py_error; - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, - error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return {}; return obj->GetBooleanValue(); @@ -134,8 +131,7 @@ lldb::offset_t ScriptedProcessPythonInterface::WriteMemoryAtAddress( StructuredData::ObjectSP obj = Dispatch("write_memory_at_address", py_error, addr, data_sp, error); - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, - error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return LLDB_INVALID_OFFSET; // If there was an error on the python call, surface it to the user. @@ -150,8 +146,7 @@ StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() { StructuredData::ArraySP array = Dispatch("get_loaded_images", error); - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, array, - error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, array, error)) return {}; return array; @@ -161,8 +156,7 @@ lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() { Status error; StructuredData::ObjectSP obj = Dispatch("get_process_id", error); - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, - error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return LLDB_INVALID_PROCESS_ID; return obj->GetUnsignedIntegerValue(LLDB_INVALID_PROCESS_ID); @@ -172,8 +166,7 @@ bool ScriptedProcessPythonInterface::IsAlive() { Status error; StructuredData::ObjectSP obj = Dispatch("is_alive", error); - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, - error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return {}; return obj->GetBooleanValue(); @@ -184,8 +177,7 @@ ScriptedProcessPythonInterface::GetScriptedThreadPluginName() { Status error; StructuredData::ObjectSP obj = Dispatch("get_scripted_thread_plugin", error); - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, - error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return {}; return obj->GetStringValue().str(); @@ -201,8 +193,7 @@ StructuredData::DictionarySP ScriptedProcessPythonInterface::GetMetadata() { StructuredData::DictionarySP dict = Dispatch("get_process_metadata", error); - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, - error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error)) return {}; return dict; diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp index 7d072212676e13..6f22503b279ca6 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp @@ -26,15 +26,6 @@ ScriptedPythonInterface::ScriptedPythonInterface( ScriptInterpreterPythonImpl &interpreter) : ScriptedInterface(), m_interpreter(interpreter) {} -template <> -void ScriptedPythonInterface::ReverseTransform( - lldb_private::Stream *&original_arg, python::PythonObject transformed_arg, - Status &error) { - Stream *s = ExtractValueFromPythonObject(transformed_arg, error); - *original_arg = *s; - original_arg->PutCString(static_cast(s)->GetData()); -} - template <> StructuredData::ArraySP ScriptedPythonInterface::ExtractValueFromPythonObject( @@ -57,33 +48,12 @@ Status ScriptedPythonInterface::ExtractValueFromPythonObject( if (lldb::SBError *sb_error = reinterpret_cast( python::LLDBSWIGPython_CastPyObjectToSBError(p.get()))) return m_interpreter.GetStatusFromSBError(*sb_error); - error.SetErrorString("Couldn't cast lldb::SBError to lldb::Status."); + else + error.SetErrorString("Couldn't cast lldb::SBError to lldb::Status."); return {}; } -template <> -Event *ScriptedPythonInterface::ExtractValueFromPythonObject( - python::PythonObject &p, Status &error) { - if (lldb::SBEvent *sb_event = reinterpret_cast( - python::LLDBSWIGPython_CastPyObjectToSBEvent(p.get()))) - return m_interpreter.GetOpaqueTypeFromSBEvent(*sb_event); - error.SetErrorString("Couldn't cast lldb::SBEvent to lldb_private::Event."); - - return nullptr; -} - -template <> -Stream *ScriptedPythonInterface::ExtractValueFromPythonObject( - python::PythonObject &p, Status &error) { - if (lldb::SBStream *sb_stream = reinterpret_cast( - python::LLDBSWIGPython_CastPyObjectToSBStream(p.get()))) - return m_interpreter.GetOpaqueTypeFromSBStream(*sb_stream); - error.SetErrorString("Couldn't cast lldb::SBStream to lldb_private::Stream."); - - return nullptr; -} - template <> lldb::DataExtractorSP ScriptedPythonInterface::ExtractValueFromPythonObject( diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h index 062bf1fcff4ac4..163659234466d3 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h @@ -115,7 +115,7 @@ class ScriptedPythonInterface : virtual public ScriptedInterface { PythonObject::ResolveNameWithDictionary( class_name, dict); if (!init.IsAllocated()) - return create_error(llvm::formatv("Could not find script class: {0}", + return create_error(llvm::formatv("Could not find script class: %s", class_name.data())); std::tuple original_args = std::forward_as_tuple(args...); @@ -248,11 +248,8 @@ class ScriptedPythonInterface : virtual public ScriptedInterface { (PyObject *)m_object_instance_sp->GetValue()); if (!implementor.IsAllocated()) - return llvm::is_contained(GetAbstractMethods(), method_name) - ? ErrorWithMessage(caller_signature, - "Python implementor not allocated.", - error) - : T{}; + return ErrorWithMessage(caller_signature, + "Python implementor not allocated.", error); std::tuple original_args = std::forward_as_tuple(args...); auto transformed_args = TransformArgs(original_args); @@ -325,10 +322,6 @@ class ScriptedPythonInterface : virtual public ScriptedInterface { return python::SWIGBridge::ToSWIGWrapper(arg); } - python::PythonObject Transform(lldb::ThreadPlanSP arg) { - return python::SWIGBridge::ToSWIGWrapper(arg); - } - python::PythonObject Transform(lldb::ProcessAttachInfoSP arg) { return python::SWIGBridge::ToSWIGWrapper(arg); } @@ -337,14 +330,6 @@ class ScriptedPythonInterface : virtual public ScriptedInterface { return python::SWIGBridge::ToSWIGWrapper(arg); } - python::PythonObject Transform(Event *arg) { - return python::SWIGBridge::ToSWIGWrapper(arg); - } - - python::PythonObject Transform(Stream *arg) { - return python::SWIGBridge::ToSWIGWrapper(arg); - } - python::PythonObject Transform(lldb::DataExtractorSP arg) { return python::SWIGBridge::ToSWIGWrapper(arg); } @@ -442,14 +427,6 @@ template <> Status ScriptedPythonInterface::ExtractValueFromPythonObject( python::PythonObject &p, Status &error); -template <> -Event *ScriptedPythonInterface::ExtractValueFromPythonObject( - python::PythonObject &p, Status &error); - -template <> -Stream *ScriptedPythonInterface::ExtractValueFromPythonObject( - python::PythonObject &p, Status &error); - template <> lldb::BreakpointSP ScriptedPythonInterface::ExtractValueFromPythonObject( diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.cpp deleted file mode 100644 index b7e475812f22b2..00000000000000 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.cpp +++ /dev/null @@ -1,105 +0,0 @@ -//===-- ScriptedThreadPlanPythonInterface.cpp -----------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "lldb/Host/Config.h" -#include "lldb/Utility/Log.h" -#include "lldb/lldb-enumerations.h" - -#if LLDB_ENABLE_PYTHON - -// LLDB Python header must be included first -#include "../lldb-python.h" - -#include "../SWIGPythonBridge.h" -#include "../ScriptInterpreterPythonImpl.h" -#include "ScriptedThreadPlanPythonInterface.h" - -using namespace lldb; -using namespace lldb_private; -using namespace lldb_private::python; - -ScriptedThreadPlanPythonInterface::ScriptedThreadPlanPythonInterface( - ScriptInterpreterPythonImpl &interpreter) - : ScriptedThreadPlanInterface(), ScriptedPythonInterface(interpreter) {} - -llvm::Expected -ScriptedThreadPlanPythonInterface::CreatePluginObject( - const llvm::StringRef class_name, lldb::ThreadPlanSP thread_plan_sp, - const StructuredDataImpl &args_sp) { - return ScriptedPythonInterface::CreatePluginObject(class_name, nullptr, - thread_plan_sp, args_sp); -} - -llvm::Expected -ScriptedThreadPlanPythonInterface::ExplainsStop(Event *event) { - Status error; - StructuredData::ObjectSP obj = Dispatch("explains_stop", error, event); - - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, - error)) { - if (!obj) - return false; - return error.ToError(); - } - - return obj->GetBooleanValue(); -} - -llvm::Expected -ScriptedThreadPlanPythonInterface::ShouldStop(Event *event) { - Status error; - StructuredData::ObjectSP obj = Dispatch("should_stop", error, event); - - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, - error)) { - if (!obj) - return false; - return error.ToError(); - } - - return obj->GetBooleanValue(); -} - -llvm::Expected ScriptedThreadPlanPythonInterface::IsStale() { - Status error; - StructuredData::ObjectSP obj = Dispatch("is_stale", error); - - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, - error)) { - if (!obj) - return false; - return error.ToError(); - } - - return obj->GetBooleanValue(); -} - -lldb::StateType ScriptedThreadPlanPythonInterface::GetRunState() { - Status error; - StructuredData::ObjectSP obj = Dispatch("should_step", error); - - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, - error)) - return lldb::eStateStepping; - - return static_cast(obj->GetUnsignedIntegerValue( - static_cast(lldb::eStateStepping))); -} - -llvm::Expected -ScriptedThreadPlanPythonInterface::GetStopDescription(lldb_private::Stream *s) { - Status error; - Dispatch("stop_description", error, s); - - if (error.Fail()) - return error.ToError(); - - return true; -} - -#endif diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.h deleted file mode 100644 index 33f086786c47b9..00000000000000 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.h +++ /dev/null @@ -1,48 +0,0 @@ -//===-- ScriptedThreadPlanPythonInterface.h ---------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDTHREADPLANPYTHONINTERFACE_H -#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDTHREADPLANPYTHONINTERFACE_H - -#include "lldb/Host/Config.h" - -#if LLDB_ENABLE_PYTHON - -#include "ScriptedPythonInterface.h" -#include "lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h" -#include - -namespace lldb_private { -class ScriptedThreadPlanPythonInterface : public ScriptedThreadPlanInterface, - public ScriptedPythonInterface { -public: - ScriptedThreadPlanPythonInterface(ScriptInterpreterPythonImpl &interpreter); - - llvm::Expected - CreatePluginObject(const llvm::StringRef class_name, - lldb::ThreadPlanSP thread_plan_sp, - const StructuredDataImpl &args_sp) override; - - llvm::SmallVector GetAbstractMethods() const override { - return {}; - } - - llvm::Expected ExplainsStop(Event *event) override; - - llvm::Expected ShouldStop(Event *event) override; - - llvm::Expected IsStale() override; - - lldb::StateType GetRunState() override; - - llvm::Expected GetStopDescription(lldb_private::Stream *s) override; -}; -} // namespace lldb_private - -#endif // LLDB_ENABLE_PYTHON -#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDTHREADPLANPYTHONINTERFACE_H diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp index 8af89d761764bc..18e268527eb2fb 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "lldb/Host/Config.h" -#include "lldb/Target/ExecutionContext.h" #include "lldb/Utility/Log.h" #include "lldb/lldb-enumerations.h" @@ -45,8 +44,7 @@ lldb::tid_t ScriptedThreadPythonInterface::GetThreadID() { Status error; StructuredData::ObjectSP obj = Dispatch("get_thread_id", error); - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, - error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return LLDB_INVALID_THREAD_ID; return obj->GetUnsignedIntegerValue(LLDB_INVALID_THREAD_ID); @@ -56,8 +54,7 @@ std::optional ScriptedThreadPythonInterface::GetName() { Status error; StructuredData::ObjectSP obj = Dispatch("get_name", error); - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, - error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return {}; return obj->GetStringValue().str(); @@ -67,8 +64,7 @@ lldb::StateType ScriptedThreadPythonInterface::GetState() { Status error; StructuredData::ObjectSP obj = Dispatch("get_state", error); - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, - error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return eStateInvalid; return static_cast(obj->GetUnsignedIntegerValue(eStateInvalid)); @@ -78,8 +74,7 @@ std::optional ScriptedThreadPythonInterface::GetQueue() { Status error; StructuredData::ObjectSP obj = Dispatch("get_queue", error); - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, - error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return {}; return obj->GetStringValue().str(); @@ -90,8 +85,7 @@ StructuredData::DictionarySP ScriptedThreadPythonInterface::GetStopReason() { StructuredData::DictionarySP dict = Dispatch("get_stop_reason", error); - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, - error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error)) return {}; return dict; @@ -102,8 +96,7 @@ StructuredData::ArraySP ScriptedThreadPythonInterface::GetStackFrames() { StructuredData::ArraySP arr = Dispatch("get_stackframes", error); - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr, - error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr, error)) return {}; return arr; @@ -114,8 +107,7 @@ StructuredData::DictionarySP ScriptedThreadPythonInterface::GetRegisterInfo() { StructuredData::DictionarySP dict = Dispatch("get_register_info", error); - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, - error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error)) return {}; return dict; @@ -125,8 +117,7 @@ std::optional ScriptedThreadPythonInterface::GetRegisterContext() { Status error; StructuredData::ObjectSP obj = Dispatch("get_register_context", error); - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, - error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return {}; return obj->GetAsString()->GetValue().str(); @@ -137,8 +128,7 @@ StructuredData::ArraySP ScriptedThreadPythonInterface::GetExtendedInfo() { StructuredData::ArraySP arr = Dispatch("get_extended_info", error); - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr, - error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr, error)) return {}; return arr; diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h index 95eb5a782097bb..c1a11b9134d62b 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h @@ -97,14 +97,12 @@ class SWIGBridge { static PythonObject ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp); static PythonObject ToSWIGWrapper(const TypeSummaryOptions &summary_options); static PythonObject ToSWIGWrapper(const SymbolContext &sym_ctx); - static PythonObject ToSWIGWrapper(const Stream *stream); - static PythonObject ToSWIGWrapper(std::shared_ptr stream_sb); - static PythonObject ToSWIGWrapper(Event *event); static PythonObject ToSWIGWrapper(lldb::ProcessAttachInfoSP attach_info_sp); static PythonObject ToSWIGWrapper(lldb::ProcessLaunchInfoSP launch_info_sp); static PythonObject ToSWIGWrapper(lldb::DataExtractorSP data_extractor_sp); + static PythonObject ToSWIGWrapper(std::unique_ptr stream_sb); static PythonObject ToSWIGWrapper(std::unique_ptr data_sb); static PythonObject @@ -114,6 +112,7 @@ class SWIGBridge { static python::ScopedPythonObject ToSWIGWrapper(CommandReturnObject &cmd_retobj); + static python::ScopedPythonObject ToSWIGWrapper(Event *event); // These prototypes are the Pythonic implementations of the required // callbacks. Although these are scripting-language specific, their definition // depends on the public API. @@ -148,6 +147,21 @@ class SWIGBridge { const char *session_dictionary_name, lldb::DebuggerSP debugger_sp); + static python::PythonObject LLDBSwigPythonCreateScriptedThreadPlan( + const char *python_class_name, const char *session_dictionary_name, + const StructuredDataImpl &args_data, std::string &error_string, + const lldb::ThreadPlanSP &thread_plan_sp); + + static bool LLDBSWIGPythonCallThreadPlan(void *implementor, + const char *method_name, + lldb_private::Event *event_sp, + bool &got_error); + + static bool LLDBSWIGPythonCallThreadPlan(void *implementor, + const char *method_name, + lldb_private::Stream *stream, + bool &got_error); + static python::PythonObject LLDBSwigPythonCreateScriptedBreakpointResolver( const char *python_class_name, const char *session_dictionary_name, const StructuredDataImpl &args, const lldb::BreakpointSP &bkpt_sp); @@ -255,8 +269,6 @@ void *LLDBSWIGPython_CastPyObjectToSBBreakpoint(PyObject *data); void *LLDBSWIGPython_CastPyObjectToSBAttachInfo(PyObject *data); void *LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data); void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data); -void *LLDBSWIGPython_CastPyObjectToSBEvent(PyObject *data); -void *LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data); void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data); void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data); } // namespace python diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp index 58ef8f674f7258..ce52f359524785 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -17,7 +17,6 @@ #include "Interfaces/OperatingSystemPythonInterface.h" #include "Interfaces/ScriptedPlatformPythonInterface.h" #include "Interfaces/ScriptedProcessPythonInterface.h" -#include "Interfaces/ScriptedThreadPlanPythonInterface.h" #include "Interfaces/ScriptedThreadPythonInterface.h" #include "PythonDataObjects.h" #include "PythonReadline.h" @@ -1538,11 +1537,6 @@ ScriptInterpreterPythonImpl::CreateScriptedThreadInterface() { return std::make_shared(*this); } -ScriptedThreadPlanInterfaceSP -ScriptInterpreterPythonImpl::CreateScriptedThreadPlanInterface() { - return std::make_shared(*this); -} - OperatingSystemInterfaceSP ScriptInterpreterPythonImpl::CreateOperatingSystemInterface() { return std::make_shared(*this); @@ -1559,6 +1553,122 @@ ScriptInterpreterPythonImpl::CreateStructuredDataFromScriptObject( return py_obj.CreateStructuredObject(); } +StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan( + const char *class_name, const StructuredDataImpl &args_data, + std::string &error_str, lldb::ThreadPlanSP thread_plan_sp) { + if (class_name == nullptr || class_name[0] == '\0') + return StructuredData::ObjectSP(); + + if (!thread_plan_sp.get()) + return {}; + + Debugger &debugger = thread_plan_sp->GetTarget().GetDebugger(); + ScriptInterpreterPythonImpl *python_interpreter = + GetPythonInterpreter(debugger); + + if (!python_interpreter) + return {}; + + Locker py_lock(this, + Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateScriptedThreadPlan( + class_name, python_interpreter->m_dictionary_name.c_str(), args_data, + error_str, thread_plan_sp); + if (!ret_val) + return {}; + + return StructuredData::ObjectSP( + new StructuredPythonObject(std::move(ret_val))); +} + +bool ScriptInterpreterPythonImpl::ScriptedThreadPlanExplainsStop( + StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) { + bool explains_stop = true; + StructuredData::Generic *generic = nullptr; + if (implementor_sp) + generic = implementor_sp->GetAsGeneric(); + if (generic) { + Locker py_lock(this, + Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + explains_stop = SWIGBridge::LLDBSWIGPythonCallThreadPlan( + generic->GetValue(), "explains_stop", event, script_error); + if (script_error) + return true; + } + return explains_stop; +} + +bool ScriptInterpreterPythonImpl::ScriptedThreadPlanShouldStop( + StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) { + bool should_stop = true; + StructuredData::Generic *generic = nullptr; + if (implementor_sp) + generic = implementor_sp->GetAsGeneric(); + if (generic) { + Locker py_lock(this, + Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + should_stop = SWIGBridge::LLDBSWIGPythonCallThreadPlan( + generic->GetValue(), "should_stop", event, script_error); + if (script_error) + return true; + } + return should_stop; +} + +bool ScriptInterpreterPythonImpl::ScriptedThreadPlanIsStale( + StructuredData::ObjectSP implementor_sp, bool &script_error) { + bool is_stale = true; + StructuredData::Generic *generic = nullptr; + if (implementor_sp) + generic = implementor_sp->GetAsGeneric(); + if (generic) { + Locker py_lock(this, + Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + is_stale = SWIGBridge::LLDBSWIGPythonCallThreadPlan( + generic->GetValue(), "is_stale", (Event *)nullptr, script_error); + if (script_error) + return true; + } + return is_stale; +} + +lldb::StateType ScriptInterpreterPythonImpl::ScriptedThreadPlanGetRunState( + StructuredData::ObjectSP implementor_sp, bool &script_error) { + bool should_step = false; + StructuredData::Generic *generic = nullptr; + if (implementor_sp) + generic = implementor_sp->GetAsGeneric(); + if (generic) { + Locker py_lock(this, + Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + should_step = SWIGBridge::LLDBSWIGPythonCallThreadPlan( + generic->GetValue(), "should_step", (Event *)nullptr, script_error); + if (script_error) + should_step = true; + } + if (should_step) + return lldb::eStateStepping; + return lldb::eStateRunning; +} + +bool +ScriptInterpreterPythonImpl::ScriptedThreadPlanGetStopDescription( + StructuredData::ObjectSP implementor_sp, lldb_private::Stream *stream, + bool &script_error) { + StructuredData::Generic *generic = nullptr; + if (implementor_sp) + generic = implementor_sp->GetAsGeneric(); + if (!generic) { + script_error = true; + return false; + } + Locker py_lock(this, + Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + return SWIGBridge::LLDBSWIGPythonCallThreadPlan( + generic->GetValue(), "stop_description", stream, script_error); +} + + StructuredData::GenericSP ScriptInterpreterPythonImpl::CreateScriptedBreakpointResolver( const char *class_name, const StructuredDataImpl &args_data, diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h index fa23540534738b..fcd21dff612b1e 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h @@ -77,9 +77,34 @@ class ScriptInterpreterPythonImpl : public ScriptInterpreterPython { StructuredData::GenericSP CreateScriptCommandObject(const char *class_name) override; + StructuredData::ObjectSP + CreateScriptedThreadPlan(const char *class_name, + const StructuredDataImpl &args_data, + std::string &error_str, + lldb::ThreadPlanSP thread_plan) override; + StructuredData::ObjectSP CreateStructuredDataFromScriptObject(ScriptObject obj) override; + bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp, + Event *event, + bool &script_error) override; + + bool ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp, + Event *event, bool &script_error) override; + + bool ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp, + bool &script_error) override; + + lldb::StateType + ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, + bool &script_error) override; + + bool + ScriptedThreadPlanGetStopDescription(StructuredData::ObjectSP implementor_sp, + lldb_private::Stream *s, + bool &script_error) override; + StructuredData::GenericSP CreateScriptedBreakpointResolver(const char *class_name, const StructuredDataImpl &args_data, @@ -111,9 +136,6 @@ class ScriptInterpreterPythonImpl : public ScriptInterpreterPython { lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override; - lldb::ScriptedThreadPlanInterfaceSP - CreateScriptedThreadPlanInterface() override; - lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() override; StructuredData::ObjectSP diff --git a/lldb/source/Target/ThreadPlanPython.cpp b/lldb/source/Target/ThreadPlanPython.cpp index 65d1737c2dc566..d6de6b3c3cf049 100644 --- a/lldb/source/Target/ThreadPlanPython.cpp +++ b/lldb/source/Target/ThreadPlanPython.cpp @@ -10,7 +10,6 @@ #include "lldb/Core/Debugger.h" #include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h" #include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" @@ -33,23 +32,6 @@ ThreadPlanPython::ThreadPlanPython(Thread &thread, const char *class_name, eVoteNoOpinion, eVoteNoOpinion), m_class_name(class_name), m_args_data(args_data), m_did_push(false), m_stop_others(false) { - ScriptInterpreter *interpreter = GetScriptInterpreter(); - if (!interpreter) { - SetPlanComplete(false); - // FIXME: error handling - return; - } - - m_interface = interpreter->CreateScriptedThreadPlanInterface(); - if (!m_interface) { - SetPlanComplete(false); - // FIXME: error handling - // error.SetErrorStringWithFormat( - // "ThreadPlanPython::%s () - ERROR: %s", __FUNCTION__, - // "Script interpreter couldn't create Scripted Thread Plan Interface"); - return; - } - SetIsControllingPlan(true); SetOkayToDiscard(true); SetPrivate(false); @@ -78,14 +60,13 @@ void ThreadPlanPython::DidPush() { // We set up the script side in DidPush, so that it can push other plans in // the constructor, and doesn't have to care about the details of DidPush. m_did_push = true; - if (m_interface) { - auto obj_or_err = m_interface->CreatePluginObject( - m_class_name, this->shared_from_this(), m_args_data); - if (!obj_or_err) { - m_error_str = llvm::toString(obj_or_err.takeError()); - SetPlanComplete(false); - } else - m_implementation_sp = *obj_or_err; + if (!m_class_name.empty()) { + ScriptInterpreter *script_interp = GetScriptInterpreter(); + if (script_interp) { + m_implementation_sp = script_interp->CreateScriptedThreadPlan( + m_class_name.c_str(), m_args_data, m_error_str, + this->shared_from_this()); + } } } @@ -96,13 +77,14 @@ bool ThreadPlanPython::ShouldStop(Event *event_ptr) { bool should_stop = true; if (m_implementation_sp) { - auto should_stop_or_err = m_interface->ShouldStop(event_ptr); - if (!should_stop_or_err) { - LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), should_stop_or_err.takeError(), - "Can't call ScriptedThreadPlan::ShouldStop."); - SetPlanComplete(false); - } else - should_stop = *should_stop_or_err; + ScriptInterpreter *script_interp = GetScriptInterpreter(); + if (script_interp) { + bool script_error; + should_stop = script_interp->ScriptedThreadPlanShouldStop( + m_implementation_sp, event_ptr, script_error); + if (script_error) + SetPlanComplete(false); + } } return should_stop; } @@ -114,13 +96,14 @@ bool ThreadPlanPython::IsPlanStale() { bool is_stale = true; if (m_implementation_sp) { - auto is_stale_or_err = m_interface->IsStale(); - if (!is_stale_or_err) { - LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), is_stale_or_err.takeError(), - "Can't call ScriptedThreadPlan::IsStale."); - SetPlanComplete(false); - } else - is_stale = *is_stale_or_err; + ScriptInterpreter *script_interp = GetScriptInterpreter(); + if (script_interp) { + bool script_error; + is_stale = script_interp->ScriptedThreadPlanIsStale(m_implementation_sp, + script_error); + if (script_error) + SetPlanComplete(false); + } } return is_stale; } @@ -132,14 +115,14 @@ bool ThreadPlanPython::DoPlanExplainsStop(Event *event_ptr) { bool explains_stop = true; if (m_implementation_sp) { - auto explains_stop_or_error = m_interface->ExplainsStop(event_ptr); - if (!explains_stop_or_error) { - LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), - explains_stop_or_error.takeError(), - "Can't call ScriptedThreadPlan::ExplainsStop."); - SetPlanComplete(false); - } else - explains_stop = *explains_stop_or_error; + ScriptInterpreter *script_interp = GetScriptInterpreter(); + if (script_interp) { + bool script_error; + explains_stop = script_interp->ScriptedThreadPlanExplainsStop( + m_implementation_sp, event_ptr, script_error); + if (script_error) + SetPlanComplete(false); + } } return explains_stop; } @@ -167,8 +150,14 @@ lldb::StateType ThreadPlanPython::GetPlanRunState() { LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION, m_class_name.c_str()); lldb::StateType run_state = eStateRunning; - if (m_implementation_sp) - run_state = m_interface->GetRunState(); + if (m_implementation_sp) { + ScriptInterpreter *script_interp = GetScriptInterpreter(); + if (script_interp) { + bool script_error; + run_state = script_interp->ScriptedThreadPlanGetRunState( + m_implementation_sp, script_error); + } + } return run_state; } @@ -179,13 +168,12 @@ void ThreadPlanPython::GetDescription(Stream *s, lldb::DescriptionLevel level) { if (m_implementation_sp) { ScriptInterpreter *script_interp = GetScriptInterpreter(); if (script_interp) { - auto desc_or_err = m_interface->GetStopDescription(s); - if (!desc_or_err || !*desc_or_err) { - LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), desc_or_err.takeError(), - "Can't call ScriptedThreadPlan::GetStopDescription."); + bool script_error; + bool added_desc = script_interp->ScriptedThreadPlanGetStopDescription( + m_implementation_sp, s, script_error); + if (script_error || !added_desc) s->Printf("Python thread plan implemented by class %s.", m_class_name.c_str()); - } } return; } diff --git a/lldb/test/API/functionalities/step_scripted/Steps.py b/lldb/test/API/functionalities/step_scripted/Steps.py index 3325dba7536571..7527607be847a5 100644 --- a/lldb/test/API/functionalities/step_scripted/Steps.py +++ b/lldb/test/API/functionalities/step_scripted/Steps.py @@ -47,7 +47,7 @@ def queue_child_thread_plan(self): # This plan does a step-over until a variable changes value. class StepUntil(StepWithChild): - def __init__(self, thread_plan, args_data): + def __init__(self, thread_plan, args_data, dict): self.thread_plan = thread_plan self.frame = thread_plan.GetThread().frames[0] self.target = thread_plan.GetThread().GetProcess().GetTarget() @@ -99,7 +99,7 @@ def stop_description(self, stream): class StepReportsStopOthers: stop_mode_dict = {} - def __init__(self, thread_plan, args_data): + def __init__(self, thread_plan, args_data, dict): self.thread_plan = thread_plan self.key = str(args_data.GetValueForKey("token").GetUnsignedIntegerValue(1000)) diff --git a/lldb/test/API/functionalities/thread_plan/wrap_step_over.py b/lldb/test/API/functionalities/thread_plan/wrap_step_over.py index ebb795abfa0e27..802aaf2d3ffdb1 100644 --- a/lldb/test/API/functionalities/thread_plan/wrap_step_over.py +++ b/lldb/test/API/functionalities/thread_plan/wrap_step_over.py @@ -2,7 +2,7 @@ class WrapStepOver: - def __init__(self, thread_plan, args_data): + def __init__(self, thread_plan, args_data, dict): self.plan = thread_plan thread = thread_plan.GetThread() target = thread.GetProcess().GetTarget() diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp index 017953b372e3e2..23162436d42c94 100644 --- a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp +++ b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp @@ -80,6 +80,26 @@ lldb_private::python::SWIGBridge::LLDBSwigPythonCreateCommandObject( return python::PythonObject(); } +python::PythonObject +lldb_private::python::SWIGBridge::LLDBSwigPythonCreateScriptedThreadPlan( + const char *python_class_name, const char *session_dictionary_name, + const StructuredDataImpl &args_data, std::string &error_string, + const lldb::ThreadPlanSP &thread_plan_sp) { + return python::PythonObject(); +} + +bool lldb_private::python::SWIGBridge::LLDBSWIGPythonCallThreadPlan( + void *implementor, const char *method_name, Event *event_sp, + bool &got_error) { + return false; +} + +bool lldb_private::python::SWIGBridge::LLDBSWIGPythonCallThreadPlan( + void *implementor, const char *method_name, Stream *event_sp, + bool &got_error) { + return false; +} + python::PythonObject lldb_private::python::SWIGBridge:: LLDBSwigPythonCreateScriptedBreakpointResolver( const char *python_class_name, const char *session_dictionary_name, @@ -134,16 +154,6 @@ lldb_private::python::LLDBSWIGPython_CastPyObjectToSBError(PyObject *data) { return nullptr; } -void * -lldb_private::python::LLDBSWIGPython_CastPyObjectToSBEvent(PyObject *data) { - return nullptr; -} - -void * -lldb_private::python::LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data) { - return nullptr; -} - void * lldb_private::python::LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data) { return nullptr; @@ -301,11 +311,6 @@ lldb_private::python::SWIGBridge::ToSWIGWrapper(lldb::ExecutionContextRefSP) { return python::PythonObject(); } -python::PythonObject -lldb_private::python::SWIGBridge::ToSWIGWrapper(lldb::ThreadPlanSP) { - return python::PythonObject(); -} - python::PythonObject lldb_private::python::SWIGBridge::ToSWIGWrapper(lldb::ProcessSP) { return python::PythonObject(); @@ -315,18 +320,3 @@ python::PythonObject lldb_private::python::SWIGBridge::ToSWIGWrapper( const lldb_private::StructuredDataImpl &) { return python::PythonObject(); } - -python::PythonObject -lldb_private::python::SWIGBridge::ToSWIGWrapper(Event *event) { - return python::PythonObject(); -} - -python::PythonObject -lldb_private::python::SWIGBridge::ToSWIGWrapper(const Stream *stream) { - return python::PythonObject(); -} - -python::PythonObject lldb_private::python::SWIGBridge::ToSWIGWrapper( - std::shared_ptr stream_sb) { - return python::PythonObject(); -}