[lldb] Make use of Scripted{Python,}Interface for ScriptedThreadPlan (#70392)
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.
Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
This commit is contained in:
committed by
GitHub
parent
c2f642d90d
commit
4b3cd379cc
@@ -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 *implementor, 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 *>(implementor));
|
||||
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 *implementor, 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 *>(implementor));
|
||||
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,
|
||||
@@ -502,7 +375,7 @@ bool lldb_private::python::SWIGBridge::LLDBSwigPythonStopHookCallHandleStop(
|
||||
|
||||
auto *sb_stream = new lldb::SBStream();
|
||||
PythonObject sb_stream_arg =
|
||||
SWIGBridge::ToSWIGWrapper(std::unique_ptr<lldb::SBStream>(sb_stream));
|
||||
SWIGBridge::ToSWIGWrapper(stream.get());
|
||||
PythonObject result =
|
||||
pfunc(SWIGBridge::ToSWIGWrapper(std::move(exc_ctx_sp)), sb_stream_arg);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user