Skip to content

Commit 11f97a7

Browse files
medismailbenAlexisPerry
authored andcommitted
[lldb] Make use of Scripted{Python,}Interface for ScriptedThreadPlan (llvm#70392) (llvm#96868)
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 llvm#70392 after fixing test failures. Signed-off-by: Med Ismail Bennani <[email protected]>
1 parent 040270d commit 11f97a7

25 files changed

+471
-431
lines changed

lldb/bindings/python/python-swigsafecast.swig

+10-7
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,6 @@ PythonObject SWIGBridge::ToSWIGWrapper(const Status& status) {
3737
return ToSWIGHelper(new lldb::SBError(status), SWIGTYPE_p_lldb__SBError);
3838
}
3939

40-
PythonObject SWIGBridge::ToSWIGWrapper(std::unique_ptr<lldb::SBStream> stream_sb) {
41-
return ToSWIGHelper(stream_sb.release(), SWIGTYPE_p_lldb__SBStream);
42-
}
43-
4440
PythonObject SWIGBridge::ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb) {
4541
return ToSWIGHelper(data_sb.release(), SWIGTYPE_p_lldb__SBStructuredData);
4642
}
@@ -115,9 +111,16 @@ SWIGBridge::ToSWIGWrapper(CommandReturnObject &cmd_retobj) {
115111
SWIGTYPE_p_lldb__SBCommandReturnObject);
116112
}
117113

118-
ScopedPythonObject<lldb::SBEvent> SWIGBridge::ToSWIGWrapper(Event *event) {
119-
return ScopedPythonObject<lldb::SBEvent>(new lldb::SBEvent(event),
120-
SWIGTYPE_p_lldb__SBEvent);
114+
PythonObject SWIGBridge::ToSWIGWrapper(const Stream *s) {
115+
return ToSWIGHelper(new lldb::SBStream(), SWIGTYPE_p_lldb__SBStream);
116+
}
117+
118+
PythonObject SWIGBridge::ToSWIGWrapper(std::shared_ptr<lldb::SBStream> stream_sb) {
119+
return ToSWIGHelper(stream_sb.get(), SWIGTYPE_p_lldb__SBStream);
120+
}
121+
122+
PythonObject SWIGBridge::ToSWIGWrapper(Event *event) {
123+
return ToSWIGHelper(new lldb::SBEvent(event), SWIGTYPE_p_lldb__SBEvent);
121124
}
122125

123126
PythonObject SWIGBridge::ToSWIGWrapper(

lldb/bindings/python/python-wrapper.swig

+27-130
Original file line numberDiff line numberDiff line change
@@ -229,133 +229,6 @@ PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateCommandObject
229229
return pfunc(SWIGBridge::ToSWIGWrapper(std::move(debugger_sp)), dict);
230230
}
231231

232-
PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateScriptedThreadPlan(
233-
const char *python_class_name, const char *session_dictionary_name,
234-
const lldb_private::StructuredDataImpl &args_impl,
235-
std::string &error_string, const lldb::ThreadPlanSP &thread_plan_sp) {
236-
if (python_class_name == NULL || python_class_name[0] == '\0' ||
237-
!session_dictionary_name)
238-
return PythonObject();
239-
240-
PyErr_Cleaner py_err_cleaner(true);
241-
242-
auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
243-
session_dictionary_name);
244-
auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
245-
python_class_name, dict);
246-
247-
if (!pfunc.IsAllocated()) {
248-
error_string.append("could not find script class: ");
249-
error_string.append(python_class_name);
250-
return PythonObject();
251-
}
252-
253-
PythonObject tp_arg = SWIGBridge::ToSWIGWrapper(thread_plan_sp);
254-
255-
llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
256-
if (!arg_info) {
257-
llvm::handleAllErrors(
258-
arg_info.takeError(),
259-
[&](PythonException &E) { error_string.append(E.ReadBacktrace()); },
260-
[&](const llvm::ErrorInfoBase &E) {
261-
error_string.append(E.message());
262-
});
263-
return PythonObject();
264-
}
265-
266-
PythonObject result = {};
267-
auto args_sb = std::unique_ptr<lldb::SBStructuredData>(new lldb::SBStructuredData(args_impl));
268-
if (arg_info.get().max_positional_args == 2) {
269-
if (args_sb->IsValid()) {
270-
error_string.assign(
271-
"args passed, but __init__ does not take an args dictionary");
272-
return PythonObject();
273-
}
274-
result = pfunc(tp_arg, dict);
275-
} else if (arg_info.get().max_positional_args >= 3) {
276-
result = pfunc(tp_arg, SWIGBridge::ToSWIGWrapper(std::move(args_sb)), dict);
277-
} else {
278-
error_string.assign("wrong number of arguments in __init__, should be 2 or "
279-
"3 (not including self)");
280-
return PythonObject();
281-
}
282-
283-
// FIXME: At this point we should check that the class we found supports all
284-
// the methods that we need.
285-
286-
return result;
287-
}
288-
289-
bool lldb_private::python::SWIGBridge::LLDBSWIGPythonCallThreadPlan(
290-
void *implementer, const char *method_name, lldb_private::Event *event,
291-
bool &got_error) {
292-
got_error = false;
293-
294-
PyErr_Cleaner py_err_cleaner(false);
295-
PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementer));
296-
auto pfunc = self.ResolveName<PythonCallable>(method_name);
297-
298-
if (!pfunc.IsAllocated())
299-
return false;
300-
301-
PythonObject result;
302-
if (event != nullptr) {
303-
ScopedPythonObject<SBEvent> event_arg = SWIGBridge::ToSWIGWrapper(event);
304-
result = pfunc(event_arg.obj());
305-
} else
306-
result = pfunc();
307-
308-
if (PyErr_Occurred()) {
309-
got_error = true;
310-
printf("Return value was neither false nor true for call to %s.\n",
311-
method_name);
312-
PyErr_Print();
313-
return false;
314-
}
315-
316-
if (result.get() == Py_True)
317-
return true;
318-
else if (result.get() == Py_False)
319-
return false;
320-
321-
// Somebody returned the wrong thing...
322-
got_error = true;
323-
printf("Wrong return value type for call to %s.\n", method_name);
324-
return false;
325-
}
326-
327-
bool lldb_private::python::SWIGBridge::LLDBSWIGPythonCallThreadPlan(
328-
void *implementer, const char *method_name, lldb_private::Stream *stream,
329-
bool &got_error) {
330-
got_error = false;
331-
332-
PyErr_Cleaner py_err_cleaner(false);
333-
PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementer));
334-
auto pfunc = self.ResolveName<PythonCallable>(method_name);
335-
336-
if (!pfunc.IsAllocated())
337-
return false;
338-
339-
auto *sb_stream = new lldb::SBStream();
340-
PythonObject sb_stream_arg =
341-
SWIGBridge::ToSWIGWrapper(std::unique_ptr<lldb::SBStream>(sb_stream));
342-
343-
PythonObject result;
344-
result = pfunc(sb_stream_arg);
345-
346-
if (PyErr_Occurred()) {
347-
printf("Error occured for call to %s.\n",
348-
method_name);
349-
PyErr_Print();
350-
got_error = true;
351-
return false;
352-
}
353-
if (stream)
354-
stream->PutCString(sb_stream->GetData());
355-
return true;
356-
357-
}
358-
359232
PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateScriptedBreakpointResolver(
360233
const char *python_class_name, const char *session_dictionary_name,
361234
const StructuredDataImpl &args_impl,
@@ -500,9 +373,8 @@ bool lldb_private::python::SWIGBridge::LLDBSwigPythonStopHookCallHandleStop(
500373
if (!pfunc.IsAllocated())
501374
return true;
502375

503-
auto *sb_stream = new lldb::SBStream();
504-
PythonObject sb_stream_arg =
505-
SWIGBridge::ToSWIGWrapper(std::unique_ptr<lldb::SBStream>(sb_stream));
376+
std::shared_ptr<lldb::SBStream> sb_stream = std::make_shared<lldb::SBStream>();
377+
PythonObject sb_stream_arg = SWIGBridge::ToSWIGWrapper(sb_stream);
506378
PythonObject result =
507379
pfunc(SWIGBridge::ToSWIGWrapper(std::move(exc_ctx_sp)), sb_stream_arg);
508380

@@ -517,6 +389,7 @@ bool lldb_private::python::SWIGBridge::LLDBSwigPythonStopHookCallHandleStop(
517389
// makes an internally help StreamString which I can't interpose, so I
518390
// have to copy it over here.
519391
stream->PutCString(sb_stream->GetData());
392+
sb_stream_arg.release();
520393

521394
if (result.get() == Py_False)
522395
return false;
@@ -753,6 +626,30 @@ void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBError(PyObject * data
753626
return sb_ptr;
754627
}
755628

629+
void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBEvent(PyObject * data) {
630+
lldb::SBEvent *sb_ptr = nullptr;
631+
632+
int valid_cast =
633+
SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBEvent, 0);
634+
635+
if (valid_cast == -1)
636+
return NULL;
637+
638+
return sb_ptr;
639+
}
640+
641+
void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBStream(PyObject * data) {
642+
lldb::SBStream *sb_ptr = nullptr;
643+
644+
int valid_cast =
645+
SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBStream, 0);
646+
647+
if (valid_cast == -1)
648+
return NULL;
649+
650+
return sb_ptr;
651+
}
652+
756653
void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBValue(PyObject * data) {
757654
lldb::SBValue *sb_ptr = NULL;
758655

lldb/include/lldb/API/SBEvent.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <vector>
1616

1717
namespace lldb_private {
18+
class ScriptInterpreter;
1819
namespace python {
1920
class SWIGBridge;
2021
}
@@ -73,11 +74,12 @@ class LLDB_API SBEvent {
7374
friend class SBThread;
7475
friend class SBWatchpoint;
7576

77+
friend class lldb_private::ScriptInterpreter;
7678
friend class lldb_private::python::SWIGBridge;
7779

7880
SBEvent(lldb::EventSP &event_sp);
7981

80-
SBEvent(lldb_private::Event *event_sp);
82+
SBEvent(lldb_private::Event *event);
8183

8284
lldb::EventSP &GetSP() const;
8385

lldb/include/lldb/API/SBStream.h

+6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313

1414
#include "lldb/API/SBDefines.h"
1515

16+
namespace lldb_private {
17+
class ScriptInterpreter;
18+
} // namespace lldb_private
19+
1620
namespace lldb {
1721

1822
class LLDB_API SBStream {
@@ -103,6 +107,8 @@ class LLDB_API SBStream {
103107
friend class SBValue;
104108
friend class SBWatchpoint;
105109

110+
friend class lldb_private::ScriptInterpreter;
111+
106112
lldb_private::Stream *operator->();
107113

108114
lldb_private::Stream *get();

lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDINTERFACE_H
1111

1212
#include "lldb/Core/StructuredDataImpl.h"
13-
#include "lldb/Target/ExecutionContext.h"
1413
#include "lldb/Utility/LLDBLog.h"
1514
#include "lldb/Utility/Log.h"
1615
#include "lldb/Utility/UnimplementedError.h"
@@ -52,7 +51,8 @@ class ScriptedInterface {
5251
}
5352

5453
template <typename T = StructuredData::ObjectSP>
55-
bool CheckStructuredDataObject(llvm::StringRef caller, T obj, Status &error) {
54+
static bool CheckStructuredDataObject(llvm::StringRef caller, T obj,
55+
Status &error) {
5656
if (!obj)
5757
return ErrorWithMessage<bool>(caller, "Null Structured Data object",
5858
error);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//===-- ScriptedThreadPlanInterface.h ---------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLDB_INTERPRETER_INTERFACES_SCRIPTEDTHREADPLANINTERFACE_H
10+
#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDTHREADPLANINTERFACE_H
11+
12+
#include "lldb/lldb-private.h"
13+
14+
#include "ScriptedInterface.h"
15+
16+
namespace lldb_private {
17+
class ScriptedThreadPlanInterface : public ScriptedInterface {
18+
public:
19+
virtual llvm::Expected<StructuredData::GenericSP>
20+
CreatePluginObject(llvm::StringRef class_name,
21+
lldb::ThreadPlanSP thread_plan_sp,
22+
const StructuredDataImpl &args_sp) = 0;
23+
24+
virtual llvm::Expected<bool> ExplainsStop(Event *event) { return true; }
25+
26+
virtual llvm::Expected<bool> ShouldStop(Event *event) { return true; }
27+
28+
virtual llvm::Expected<bool> IsStale() { return true; };
29+
30+
virtual lldb::StateType GetRunState() { return lldb::eStateStepping; }
31+
32+
virtual llvm::Expected<bool> GetStopDescription(lldb_private::Stream *s) {
33+
return true;
34+
}
35+
};
36+
} // namespace lldb_private
37+
38+
#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDTHREADPLANINTERFACE_H

lldb/include/lldb/Interpreter/ScriptInterpreter.h

+11-44
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
#include "lldb/API/SBBreakpoint.h"
1414
#include "lldb/API/SBData.h"
1515
#include "lldb/API/SBError.h"
16+
#include "lldb/API/SBEvent.h"
1617
#include "lldb/API/SBLaunchInfo.h"
1718
#include "lldb/API/SBMemoryRegionInfo.h"
19+
#include "lldb/API/SBStream.h"
1820
#include "lldb/Breakpoint/BreakpointOptions.h"
1921
#include "lldb/Core/PluginInterface.h"
2022
#include "lldb/Core/SearchFilter.h"
@@ -250,50 +252,6 @@ class ScriptInterpreter : public PluginInterface {
250252
return lldb::ValueObjectListSP();
251253
}
252254

253-
virtual StructuredData::ObjectSP
254-
CreateScriptedThreadPlan(const char *class_name,
255-
const StructuredDataImpl &args_data,
256-
std::string &error_str,
257-
lldb::ThreadPlanSP thread_plan_sp) {
258-
return StructuredData::ObjectSP();
259-
}
260-
261-
virtual bool
262-
ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
263-
Event *event, bool &script_error) {
264-
script_error = true;
265-
return true;
266-
}
267-
268-
virtual bool
269-
ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp,
270-
Event *event, bool &script_error) {
271-
script_error = true;
272-
return true;
273-
}
274-
275-
virtual bool
276-
ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp,
277-
bool &script_error) {
278-
script_error = true;
279-
return true;
280-
}
281-
282-
virtual lldb::StateType
283-
ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp,
284-
bool &script_error) {
285-
script_error = true;
286-
return lldb::eStateStepping;
287-
}
288-
289-
virtual bool
290-
ScriptedThreadPlanGetStopDescription(StructuredData::ObjectSP implementor_sp,
291-
lldb_private::Stream *stream,
292-
bool &script_error) {
293-
script_error = true;
294-
return false;
295-
}
296-
297255
virtual StructuredData::GenericSP
298256
CreateScriptedBreakpointResolver(const char *class_name,
299257
const StructuredDataImpl &args_data,
@@ -592,6 +550,11 @@ class ScriptInterpreter : public PluginInterface {
592550
return {};
593551
}
594552

553+
virtual lldb::ScriptedThreadPlanInterfaceSP
554+
CreateScriptedThreadPlanInterface() {
555+
return {};
556+
}
557+
595558
virtual lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() {
596559
return {};
597560
}
@@ -610,6 +573,10 @@ class ScriptInterpreter : public PluginInterface {
610573

611574
Status GetStatusFromSBError(const lldb::SBError &error) const;
612575

576+
Event *GetOpaqueTypeFromSBEvent(const lldb::SBEvent &event) const;
577+
578+
Stream *GetOpaqueTypeFromSBStream(const lldb::SBStream &stream) const;
579+
613580
lldb::BreakpointSP
614581
GetOpaqueTypeFromSBBreakpoint(const lldb::SBBreakpoint &breakpoint) const;
615582

0 commit comments

Comments
 (0)