This patch makes ScriptedThreadPlan conforming to the ScriptedInterface
& ScriptedPythonInterface facilities by introducing 2
ScriptedThreadPlanInterface & ScriptedThreadPlanPythonInterface classes.
This allows us to get rid of every ScriptedThreadPlan-specific SWIG
method and re-use the same affordances as other scripting offordances,
like Scripted{Process,Thread,Platform} & OperatingSystem.
To do so, this adds new transformer methods for `ThreadPlan`, `Stream` &
`Event`, to allow the bijection between C++ objects and their python
counterparts.
This just re-lands #70392 after fixing test failures.
Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
This commit is contained in:
committed by
GitHub
parent
bf536cc7db
commit
9a9ec228cd
@@ -37,10 +37,6 @@ PythonObject SWIGBridge::ToSWIGWrapper(const Status& status) {
|
||||
return ToSWIGHelper(new lldb::SBError(status), SWIGTYPE_p_lldb__SBError);
|
||||
}
|
||||
|
||||
PythonObject SWIGBridge::ToSWIGWrapper(std::unique_ptr<lldb::SBStream> stream_sb) {
|
||||
return ToSWIGHelper(stream_sb.release(), SWIGTYPE_p_lldb__SBStream);
|
||||
}
|
||||
|
||||
PythonObject SWIGBridge::ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb) {
|
||||
return ToSWIGHelper(data_sb.release(), SWIGTYPE_p_lldb__SBStructuredData);
|
||||
}
|
||||
@@ -115,9 +111,16 @@ SWIGBridge::ToSWIGWrapper(CommandReturnObject &cmd_retobj) {
|
||||
SWIGTYPE_p_lldb__SBCommandReturnObject);
|
||||
}
|
||||
|
||||
ScopedPythonObject<lldb::SBEvent> SWIGBridge::ToSWIGWrapper(Event *event) {
|
||||
return ScopedPythonObject<lldb::SBEvent>(new lldb::SBEvent(event),
|
||||
SWIGTYPE_p_lldb__SBEvent);
|
||||
PythonObject SWIGBridge::ToSWIGWrapper(const Stream *s) {
|
||||
return ToSWIGHelper(new lldb::SBStream(), SWIGTYPE_p_lldb__SBStream);
|
||||
}
|
||||
|
||||
PythonObject SWIGBridge::ToSWIGWrapper(std::shared_ptr<lldb::SBStream> 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);
|
||||
}
|
||||
|
||||
PythonObject SWIGBridge::ToSWIGWrapper(
|
||||
|
||||
@@ -229,133 +229,6 @@ 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<PythonDictionary>(
|
||||
session_dictionary_name);
|
||||
auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
|
||||
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<PythonCallable::ArgInfo> 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<lldb::SBStructuredData>(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<PyObject *>(implementer));
|
||||
auto pfunc = self.ResolveName<PythonCallable>(method_name);
|
||||
|
||||
if (!pfunc.IsAllocated())
|
||||
return false;
|
||||
|
||||
PythonObject result;
|
||||
if (event != nullptr) {
|
||||
ScopedPythonObject<SBEvent> 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<PyObject *>(implementer));
|
||||
auto pfunc = self.ResolveName<PythonCallable>(method_name);
|
||||
|
||||
if (!pfunc.IsAllocated())
|
||||
return false;
|
||||
|
||||
auto *sb_stream = new lldb::SBStream();
|
||||
PythonObject sb_stream_arg =
|
||||
SWIGBridge::ToSWIGWrapper(std::unique_ptr<lldb::SBStream>(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,
|
||||
@@ -500,9 +373,8 @@ bool lldb_private::python::SWIGBridge::LLDBSwigPythonStopHookCallHandleStop(
|
||||
if (!pfunc.IsAllocated())
|
||||
return true;
|
||||
|
||||
auto *sb_stream = new lldb::SBStream();
|
||||
PythonObject sb_stream_arg =
|
||||
SWIGBridge::ToSWIGWrapper(std::unique_ptr<lldb::SBStream>(sb_stream));
|
||||
std::shared_ptr<lldb::SBStream> sb_stream = std::make_shared<lldb::SBStream>();
|
||||
PythonObject sb_stream_arg = SWIGBridge::ToSWIGWrapper(sb_stream);
|
||||
PythonObject result =
|
||||
pfunc(SWIGBridge::ToSWIGWrapper(std::move(exc_ctx_sp)), sb_stream_arg);
|
||||
|
||||
@@ -517,6 +389,7 @@ 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;
|
||||
@@ -753,6 +626,30 @@ 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;
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <vector>
|
||||
|
||||
namespace lldb_private {
|
||||
class ScriptInterpreter;
|
||||
namespace python {
|
||||
class SWIGBridge;
|
||||
}
|
||||
@@ -73,11 +74,12 @@ protected:
|
||||
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_sp);
|
||||
SBEvent(lldb_private::Event *event);
|
||||
|
||||
lldb::EventSP &GetSP() const;
|
||||
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
namespace lldb_private {
|
||||
class ScriptInterpreter;
|
||||
} // namespace lldb_private
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class LLDB_API SBStream {
|
||||
@@ -103,6 +107,8 @@ protected:
|
||||
friend class SBValue;
|
||||
friend class SBWatchpoint;
|
||||
|
||||
friend class lldb_private::ScriptInterpreter;
|
||||
|
||||
lldb_private::Stream *operator->();
|
||||
|
||||
lldb_private::Stream *get();
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#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"
|
||||
@@ -52,7 +51,8 @@ public:
|
||||
}
|
||||
|
||||
template <typename T = StructuredData::ObjectSP>
|
||||
bool CheckStructuredDataObject(llvm::StringRef caller, T obj, Status &error) {
|
||||
static bool CheckStructuredDataObject(llvm::StringRef caller, T obj,
|
||||
Status &error) {
|
||||
if (!obj)
|
||||
return ErrorWithMessage<bool>(caller, "Null Structured Data object",
|
||||
error);
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
//===-- 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<StructuredData::GenericSP>
|
||||
CreatePluginObject(llvm::StringRef class_name,
|
||||
lldb::ThreadPlanSP thread_plan_sp,
|
||||
const StructuredDataImpl &args_sp) = 0;
|
||||
|
||||
virtual llvm::Expected<bool> ExplainsStop(Event *event) { return true; }
|
||||
|
||||
virtual llvm::Expected<bool> ShouldStop(Event *event) { return true; }
|
||||
|
||||
virtual llvm::Expected<bool> IsStale() { return true; };
|
||||
|
||||
virtual lldb::StateType GetRunState() { return lldb::eStateStepping; }
|
||||
|
||||
virtual llvm::Expected<bool> GetStopDescription(lldb_private::Stream *s) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDTHREADPLANINTERFACE_H
|
||||
@@ -13,8 +13,10 @@
|
||||
#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"
|
||||
@@ -250,50 +252,6 @@ public:
|
||||
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,
|
||||
@@ -592,6 +550,11 @@ public:
|
||||
return {};
|
||||
}
|
||||
|
||||
virtual lldb::ScriptedThreadPlanInterfaceSP
|
||||
CreateScriptedThreadPlanInterface() {
|
||||
return {};
|
||||
}
|
||||
|
||||
virtual lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() {
|
||||
return {};
|
||||
}
|
||||
@@ -610,6 +573,10 @@ public:
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <string>
|
||||
|
||||
#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"
|
||||
@@ -70,6 +71,7 @@ private:
|
||||
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;
|
||||
|
||||
@@ -189,6 +189,7 @@ class ScriptedMetadata;
|
||||
class ScriptedPlatformInterface;
|
||||
class ScriptedProcessInterface;
|
||||
class ScriptedThreadInterface;
|
||||
class ScriptedThreadPlanInterface;
|
||||
class ScriptedSyntheticChildren;
|
||||
class SearchFilter;
|
||||
class Section;
|
||||
@@ -406,6 +407,8 @@ typedef std::unique_ptr<lldb_private::ScriptedProcessInterface>
|
||||
ScriptedProcessInterfaceUP;
|
||||
typedef std::shared_ptr<lldb_private::ScriptedThreadInterface>
|
||||
ScriptedThreadInterfaceSP;
|
||||
typedef std::shared_ptr<lldb_private::ScriptedThreadPlanInterface>
|
||||
ScriptedThreadPlanInterfaceSP;
|
||||
typedef std::shared_ptr<lldb_private::Section> SectionSP;
|
||||
typedef std::unique_ptr<lldb_private::SectionList> SectionListUP;
|
||||
typedef std::weak_ptr<lldb_private::Section> SectionWP;
|
||||
|
||||
@@ -101,6 +101,19 @@ 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<lldb::SBStream &>(stream).m_opaque_up.get();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::optional<MemoryRegionInfo>
|
||||
ScriptInterpreter::GetOpaqueTypeFromSBMemoryRegionInfo(
|
||||
const lldb::SBMemoryRegionInfo &mem_region) const {
|
||||
|
||||
@@ -24,6 +24,7 @@ add_lldb_library(lldbPluginScriptInterpreterPythonInterfaces
|
||||
ScriptedPythonInterface.cpp
|
||||
ScriptedProcessPythonInterface.cpp
|
||||
ScriptedThreadPythonInterface.cpp
|
||||
ScriptedThreadPlanPythonInterface.cpp
|
||||
ScriptedPlatformPythonInterface.cpp
|
||||
|
||||
LINK_LIBS
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include "../ScriptInterpreterPythonImpl.h"
|
||||
#include "ScriptedPlatformPythonInterface.h"
|
||||
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
using namespace lldb_private::python;
|
||||
|
||||
@@ -49,7 +49,8 @@ StructuredData::DictionarySP ScriptedProcessPythonInterface::GetCapabilities() {
|
||||
StructuredData::DictionarySP dict =
|
||||
Dispatch<StructuredData::DictionarySP>("get_capabilities", error);
|
||||
|
||||
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
|
||||
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict,
|
||||
error))
|
||||
return {};
|
||||
|
||||
return dict;
|
||||
@@ -90,7 +91,8 @@ StructuredData::DictionarySP ScriptedProcessPythonInterface::GetThreadsInfo() {
|
||||
StructuredData::DictionarySP dict =
|
||||
Dispatch<StructuredData::DictionarySP>("get_threads_info", error);
|
||||
|
||||
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
|
||||
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict,
|
||||
error))
|
||||
return {};
|
||||
|
||||
return dict;
|
||||
@@ -106,7 +108,8 @@ bool ScriptedProcessPythonInterface::CreateBreakpoint(lldb::addr_t addr,
|
||||
if (py_error.Fail())
|
||||
error = py_error;
|
||||
|
||||
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
|
||||
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
|
||||
error))
|
||||
return {};
|
||||
|
||||
return obj->GetBooleanValue();
|
||||
@@ -131,7 +134,8 @@ lldb::offset_t ScriptedProcessPythonInterface::WriteMemoryAtAddress(
|
||||
StructuredData::ObjectSP obj =
|
||||
Dispatch("write_memory_at_address", py_error, addr, data_sp, error);
|
||||
|
||||
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
|
||||
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
|
||||
error))
|
||||
return LLDB_INVALID_OFFSET;
|
||||
|
||||
// If there was an error on the python call, surface it to the user.
|
||||
@@ -146,7 +150,8 @@ StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() {
|
||||
StructuredData::ArraySP array =
|
||||
Dispatch<StructuredData::ArraySP>("get_loaded_images", error);
|
||||
|
||||
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, array, error))
|
||||
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, array,
|
||||
error))
|
||||
return {};
|
||||
|
||||
return array;
|
||||
@@ -156,7 +161,8 @@ lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() {
|
||||
Status error;
|
||||
StructuredData::ObjectSP obj = Dispatch("get_process_id", error);
|
||||
|
||||
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
|
||||
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
|
||||
error))
|
||||
return LLDB_INVALID_PROCESS_ID;
|
||||
|
||||
return obj->GetUnsignedIntegerValue(LLDB_INVALID_PROCESS_ID);
|
||||
@@ -166,7 +172,8 @@ bool ScriptedProcessPythonInterface::IsAlive() {
|
||||
Status error;
|
||||
StructuredData::ObjectSP obj = Dispatch("is_alive", error);
|
||||
|
||||
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
|
||||
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
|
||||
error))
|
||||
return {};
|
||||
|
||||
return obj->GetBooleanValue();
|
||||
@@ -177,7 +184,8 @@ ScriptedProcessPythonInterface::GetScriptedThreadPluginName() {
|
||||
Status error;
|
||||
StructuredData::ObjectSP obj = Dispatch("get_scripted_thread_plugin", error);
|
||||
|
||||
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
|
||||
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
|
||||
error))
|
||||
return {};
|
||||
|
||||
return obj->GetStringValue().str();
|
||||
@@ -193,7 +201,8 @@ StructuredData::DictionarySP ScriptedProcessPythonInterface::GetMetadata() {
|
||||
StructuredData::DictionarySP dict =
|
||||
Dispatch<StructuredData::DictionarySP>("get_process_metadata", error);
|
||||
|
||||
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
|
||||
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict,
|
||||
error))
|
||||
return {};
|
||||
|
||||
return dict;
|
||||
|
||||
@@ -26,6 +26,15 @@ 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<Stream *>(transformed_arg, error);
|
||||
*original_arg = *s;
|
||||
original_arg->PutCString(static_cast<StreamString *>(s)->GetData());
|
||||
}
|
||||
|
||||
template <>
|
||||
StructuredData::ArraySP
|
||||
ScriptedPythonInterface::ExtractValueFromPythonObject<StructuredData::ArraySP>(
|
||||
@@ -48,12 +57,33 @@ Status ScriptedPythonInterface::ExtractValueFromPythonObject<Status>(
|
||||
if (lldb::SBError *sb_error = reinterpret_cast<lldb::SBError *>(
|
||||
python::LLDBSWIGPython_CastPyObjectToSBError(p.get())))
|
||||
return m_interpreter.GetStatusFromSBError(*sb_error);
|
||||
else
|
||||
error.SetErrorString("Couldn't cast lldb::SBError to lldb::Status.");
|
||||
error.SetErrorString("Couldn't cast lldb::SBError to lldb::Status.");
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
template <>
|
||||
Event *ScriptedPythonInterface::ExtractValueFromPythonObject<Event *>(
|
||||
python::PythonObject &p, Status &error) {
|
||||
if (lldb::SBEvent *sb_event = reinterpret_cast<lldb::SBEvent *>(
|
||||
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<Stream *>(
|
||||
python::PythonObject &p, Status &error) {
|
||||
if (lldb::SBStream *sb_stream = reinterpret_cast<lldb::SBStream *>(
|
||||
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<lldb::DataExtractorSP>(
|
||||
|
||||
@@ -115,7 +115,7 @@ public:
|
||||
PythonObject::ResolveNameWithDictionary<python::PythonCallable>(
|
||||
class_name, dict);
|
||||
if (!init.IsAllocated())
|
||||
return create_error(llvm::formatv("Could not find script class: %s",
|
||||
return create_error(llvm::formatv("Could not find script class: {0}",
|
||||
class_name.data()));
|
||||
|
||||
std::tuple<Args...> original_args = std::forward_as_tuple(args...);
|
||||
@@ -248,8 +248,11 @@ protected:
|
||||
(PyObject *)m_object_instance_sp->GetValue());
|
||||
|
||||
if (!implementor.IsAllocated())
|
||||
return ErrorWithMessage<T>(caller_signature,
|
||||
"Python implementor not allocated.", error);
|
||||
return llvm::is_contained(GetAbstractMethods(), method_name)
|
||||
? ErrorWithMessage<T>(caller_signature,
|
||||
"Python implementor not allocated.",
|
||||
error)
|
||||
: T{};
|
||||
|
||||
std::tuple<Args...> original_args = std::forward_as_tuple(args...);
|
||||
auto transformed_args = TransformArgs(original_args);
|
||||
@@ -322,6 +325,10 @@ protected:
|
||||
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);
|
||||
}
|
||||
@@ -330,6 +337,14 @@ protected:
|
||||
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);
|
||||
}
|
||||
@@ -427,6 +442,14 @@ template <>
|
||||
Status ScriptedPythonInterface::ExtractValueFromPythonObject<Status>(
|
||||
python::PythonObject &p, Status &error);
|
||||
|
||||
template <>
|
||||
Event *ScriptedPythonInterface::ExtractValueFromPythonObject<Event *>(
|
||||
python::PythonObject &p, Status &error);
|
||||
|
||||
template <>
|
||||
Stream *ScriptedPythonInterface::ExtractValueFromPythonObject<Stream *>(
|
||||
python::PythonObject &p, Status &error);
|
||||
|
||||
template <>
|
||||
lldb::BreakpointSP
|
||||
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::BreakpointSP>(
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
//===-- 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<StructuredData::GenericSP>
|
||||
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<bool>
|
||||
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<bool>
|
||||
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<bool> 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<lldb::StateType>(obj->GetUnsignedIntegerValue(
|
||||
static_cast<uint32_t>(lldb::eStateStepping)));
|
||||
}
|
||||
|
||||
llvm::Expected<bool>
|
||||
ScriptedThreadPlanPythonInterface::GetStopDescription(lldb_private::Stream *s) {
|
||||
Status error;
|
||||
Dispatch("stop_description", error, s);
|
||||
|
||||
if (error.Fail())
|
||||
return error.ToError();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,48 @@
|
||||
//===-- 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 <optional>
|
||||
|
||||
namespace lldb_private {
|
||||
class ScriptedThreadPlanPythonInterface : public ScriptedThreadPlanInterface,
|
||||
public ScriptedPythonInterface {
|
||||
public:
|
||||
ScriptedThreadPlanPythonInterface(ScriptInterpreterPythonImpl &interpreter);
|
||||
|
||||
llvm::Expected<StructuredData::GenericSP>
|
||||
CreatePluginObject(const llvm::StringRef class_name,
|
||||
lldb::ThreadPlanSP thread_plan_sp,
|
||||
const StructuredDataImpl &args_sp) override;
|
||||
|
||||
llvm::SmallVector<llvm::StringLiteral> GetAbstractMethods() const override {
|
||||
return {};
|
||||
}
|
||||
|
||||
llvm::Expected<bool> ExplainsStop(Event *event) override;
|
||||
|
||||
llvm::Expected<bool> ShouldStop(Event *event) override;
|
||||
|
||||
llvm::Expected<bool> IsStale() override;
|
||||
|
||||
lldb::StateType GetRunState() override;
|
||||
|
||||
llvm::Expected<bool> GetStopDescription(lldb_private::Stream *s) override;
|
||||
};
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // LLDB_ENABLE_PYTHON
|
||||
#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDTHREADPLANPYTHONINTERFACE_H
|
||||
@@ -7,6 +7,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/Host/Config.h"
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
#include "lldb/Utility/Log.h"
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
|
||||
@@ -44,7 +45,8 @@ lldb::tid_t ScriptedThreadPythonInterface::GetThreadID() {
|
||||
Status error;
|
||||
StructuredData::ObjectSP obj = Dispatch("get_thread_id", error);
|
||||
|
||||
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
|
||||
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
|
||||
error))
|
||||
return LLDB_INVALID_THREAD_ID;
|
||||
|
||||
return obj->GetUnsignedIntegerValue(LLDB_INVALID_THREAD_ID);
|
||||
@@ -54,7 +56,8 @@ std::optional<std::string> ScriptedThreadPythonInterface::GetName() {
|
||||
Status error;
|
||||
StructuredData::ObjectSP obj = Dispatch("get_name", error);
|
||||
|
||||
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
|
||||
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
|
||||
error))
|
||||
return {};
|
||||
|
||||
return obj->GetStringValue().str();
|
||||
@@ -64,7 +67,8 @@ lldb::StateType ScriptedThreadPythonInterface::GetState() {
|
||||
Status error;
|
||||
StructuredData::ObjectSP obj = Dispatch("get_state", error);
|
||||
|
||||
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
|
||||
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
|
||||
error))
|
||||
return eStateInvalid;
|
||||
|
||||
return static_cast<StateType>(obj->GetUnsignedIntegerValue(eStateInvalid));
|
||||
@@ -74,7 +78,8 @@ std::optional<std::string> ScriptedThreadPythonInterface::GetQueue() {
|
||||
Status error;
|
||||
StructuredData::ObjectSP obj = Dispatch("get_queue", error);
|
||||
|
||||
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
|
||||
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
|
||||
error))
|
||||
return {};
|
||||
|
||||
return obj->GetStringValue().str();
|
||||
@@ -85,7 +90,8 @@ StructuredData::DictionarySP ScriptedThreadPythonInterface::GetStopReason() {
|
||||
StructuredData::DictionarySP dict =
|
||||
Dispatch<StructuredData::DictionarySP>("get_stop_reason", error);
|
||||
|
||||
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
|
||||
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict,
|
||||
error))
|
||||
return {};
|
||||
|
||||
return dict;
|
||||
@@ -96,7 +102,8 @@ StructuredData::ArraySP ScriptedThreadPythonInterface::GetStackFrames() {
|
||||
StructuredData::ArraySP arr =
|
||||
Dispatch<StructuredData::ArraySP>("get_stackframes", error);
|
||||
|
||||
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr, error))
|
||||
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr,
|
||||
error))
|
||||
return {};
|
||||
|
||||
return arr;
|
||||
@@ -107,7 +114,8 @@ StructuredData::DictionarySP ScriptedThreadPythonInterface::GetRegisterInfo() {
|
||||
StructuredData::DictionarySP dict =
|
||||
Dispatch<StructuredData::DictionarySP>("get_register_info", error);
|
||||
|
||||
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
|
||||
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict,
|
||||
error))
|
||||
return {};
|
||||
|
||||
return dict;
|
||||
@@ -117,7 +125,8 @@ std::optional<std::string> ScriptedThreadPythonInterface::GetRegisterContext() {
|
||||
Status error;
|
||||
StructuredData::ObjectSP obj = Dispatch("get_register_context", error);
|
||||
|
||||
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
|
||||
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
|
||||
error))
|
||||
return {};
|
||||
|
||||
return obj->GetAsString()->GetValue().str();
|
||||
@@ -128,7 +137,8 @@ StructuredData::ArraySP ScriptedThreadPythonInterface::GetExtendedInfo() {
|
||||
StructuredData::ArraySP arr =
|
||||
Dispatch<StructuredData::ArraySP>("get_extended_info", error);
|
||||
|
||||
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr, error))
|
||||
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr,
|
||||
error))
|
||||
return {};
|
||||
|
||||
return arr;
|
||||
|
||||
@@ -97,12 +97,14 @@ public:
|
||||
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<lldb::SBStream> 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<lldb::SBStream> stream_sb);
|
||||
static PythonObject
|
||||
ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb);
|
||||
static PythonObject
|
||||
@@ -112,7 +114,6 @@ public:
|
||||
|
||||
static python::ScopedPythonObject<lldb::SBCommandReturnObject>
|
||||
ToSWIGWrapper(CommandReturnObject &cmd_retobj);
|
||||
static python::ScopedPythonObject<lldb::SBEvent> 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.
|
||||
@@ -147,21 +148,6 @@ public:
|
||||
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);
|
||||
@@ -269,6 +255,8 @@ 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
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#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"
|
||||
@@ -1537,6 +1538,11 @@ ScriptInterpreterPythonImpl::CreateScriptedThreadInterface() {
|
||||
return std::make_shared<ScriptedThreadPythonInterface>(*this);
|
||||
}
|
||||
|
||||
ScriptedThreadPlanInterfaceSP
|
||||
ScriptInterpreterPythonImpl::CreateScriptedThreadPlanInterface() {
|
||||
return std::make_shared<ScriptedThreadPlanPythonInterface>(*this);
|
||||
}
|
||||
|
||||
OperatingSystemInterfaceSP
|
||||
ScriptInterpreterPythonImpl::CreateOperatingSystemInterface() {
|
||||
return std::make_shared<OperatingSystemPythonInterface>(*this);
|
||||
@@ -1553,122 +1559,6 @@ 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,
|
||||
|
||||
@@ -77,34 +77,9 @@ public:
|
||||
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,
|
||||
@@ -136,6 +111,9 @@ public:
|
||||
|
||||
lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override;
|
||||
|
||||
lldb::ScriptedThreadPlanInterfaceSP
|
||||
CreateScriptedThreadPlanInterface() override;
|
||||
|
||||
lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() override;
|
||||
|
||||
StructuredData::ObjectSP
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#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"
|
||||
@@ -32,6 +33,26 @@ 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
|
||||
// error.SetErrorStringWithFormat(
|
||||
// "ThreadPlanPython::%s () - ERROR: %s", __FUNCTION__,
|
||||
// "Couldn't get script interpreter");
|
||||
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);
|
||||
@@ -60,13 +81,14 @@ 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_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());
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,14 +99,13 @@ bool ThreadPlanPython::ShouldStop(Event *event_ptr) {
|
||||
|
||||
bool should_stop = true;
|
||||
if (m_implementation_sp) {
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
return should_stop;
|
||||
}
|
||||
@@ -96,14 +117,13 @@ bool ThreadPlanPython::IsPlanStale() {
|
||||
|
||||
bool is_stale = true;
|
||||
if (m_implementation_sp) {
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
return is_stale;
|
||||
}
|
||||
@@ -115,14 +135,14 @@ bool ThreadPlanPython::DoPlanExplainsStop(Event *event_ptr) {
|
||||
|
||||
bool explains_stop = true;
|
||||
if (m_implementation_sp) {
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
return explains_stop;
|
||||
}
|
||||
@@ -150,14 +170,8 @@ 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) {
|
||||
ScriptInterpreter *script_interp = GetScriptInterpreter();
|
||||
if (script_interp) {
|
||||
bool script_error;
|
||||
run_state = script_interp->ScriptedThreadPlanGetRunState(
|
||||
m_implementation_sp, script_error);
|
||||
}
|
||||
}
|
||||
if (m_implementation_sp)
|
||||
run_state = m_interface->GetRunState();
|
||||
return run_state;
|
||||
}
|
||||
|
||||
@@ -168,12 +182,13 @@ void ThreadPlanPython::GetDescription(Stream *s, lldb::DescriptionLevel level) {
|
||||
if (m_implementation_sp) {
|
||||
ScriptInterpreter *script_interp = GetScriptInterpreter();
|
||||
if (script_interp) {
|
||||
bool script_error;
|
||||
bool added_desc = script_interp->ScriptedThreadPlanGetStopDescription(
|
||||
m_implementation_sp, s, script_error);
|
||||
if (script_error || !added_desc)
|
||||
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.");
|
||||
s->Printf("Python thread plan implemented by class %s.",
|
||||
m_class_name.c_str());
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ class StepScripted(StepWithChild):
|
||||
|
||||
# This plan does a step-over until a variable changes value.
|
||||
class StepUntil(StepWithChild):
|
||||
def __init__(self, thread_plan, args_data, dict):
|
||||
def __init__(self, thread_plan, args_data):
|
||||
self.thread_plan = thread_plan
|
||||
self.frame = thread_plan.GetThread().frames[0]
|
||||
self.target = thread_plan.GetThread().GetProcess().GetTarget()
|
||||
@@ -99,7 +99,7 @@ class StepUntil(StepWithChild):
|
||||
class StepReportsStopOthers:
|
||||
stop_mode_dict = {}
|
||||
|
||||
def __init__(self, thread_plan, args_data, dict):
|
||||
def __init__(self, thread_plan, args_data):
|
||||
self.thread_plan = thread_plan
|
||||
self.key = str(args_data.GetValueForKey("token").GetUnsignedIntegerValue(1000))
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import lldb
|
||||
|
||||
|
||||
class WrapStepOver:
|
||||
def __init__(self, thread_plan, args_data, dict):
|
||||
def __init__(self, thread_plan, args_data):
|
||||
self.plan = thread_plan
|
||||
thread = thread_plan.GetThread()
|
||||
target = thread.GetProcess().GetTarget()
|
||||
|
||||
@@ -80,26 +80,6 @@ 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,
|
||||
@@ -154,6 +134,16 @@ 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;
|
||||
@@ -311,6 +301,11 @@ 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();
|
||||
@@ -320,3 +315,18 @@ 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<lldb::SBStream> stream_sb) {
|
||||
return python::PythonObject();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user