Skip to content

Commit 4840384

Browse files
committed
[lldb] Make use of Scripted{Python,}Interface for ScriptedThreadPlan
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 <[email protected]>
1 parent 8a786be commit 4840384

23 files changed

+401
-407
lines changed

lldb/bindings/python/python-swigsafecast.swig

+6-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,12 @@ 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(Event *event) {
119+
return ToSWIGHelper(new lldb::SBEvent(event), SWIGTYPE_p_lldb__SBEvent);
121120
}
122121

123122
PythonObject SWIGBridge::ToSWIGWrapper(

lldb/bindings/python/python-wrapper.swig

+25-128
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 *implementor, 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 *>(implementor));
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 *implementor, 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 *>(implementor));
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,
@@ -502,7 +375,7 @@ bool lldb_private::python::SWIGBridge::LLDBSwigPythonStopHookCallHandleStop(
502375

503376
auto *sb_stream = new lldb::SBStream();
504377
PythonObject sb_stream_arg =
505-
SWIGBridge::ToSWIGWrapper(std::unique_ptr<lldb::SBStream>(sb_stream));
378+
SWIGBridge::ToSWIGWrapper(stream.get());
506379
PythonObject result =
507380
pfunc(SWIGBridge::ToSWIGWrapper(std::move(exc_ctx_sp)), sb_stream_arg);
508381

@@ -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

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

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

16+
namespace lldb_private {
17+
class ScriptInterpreter;
18+
namespace python {
19+
class SWIGBridge;
20+
}
21+
} // namespace lldb_private
22+
1623
namespace lldb {
1724

1825
class LLDB_API SBStream {
@@ -101,6 +108,8 @@ class LLDB_API SBStream {
101108
friend class SBValue;
102109
friend class SBWatchpoint;
103110

111+
friend class lldb_private::ScriptInterpreter;
112+
104113
lldb_private::Stream *operator->();
105114

106115
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"
@@ -50,7 +49,8 @@ class ScriptedInterface {
5049
}
5150

5251
template <typename T = StructuredData::ObjectSP>
53-
bool CheckStructuredDataObject(llvm::StringRef caller, T obj, Status &error) {
52+
static bool CheckStructuredDataObject(llvm::StringRef caller, T obj,
53+
Status &error) {
5454
if (!obj)
5555
return ErrorWithMessage<bool>(caller, "Null Structured Data object",
5656
error);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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) {
23+
llvm_unreachable("unimplemented!");
24+
}
25+
26+
virtual llvm::Expected<bool> ExplainsStop(Event *event) { return true; }
27+
28+
virtual llvm::Expected<bool> ShouldStop(Event *event) { return true; }
29+
30+
virtual llvm::Expected<bool> IsStale() { return true; };
31+
32+
virtual lldb::StateType GetRunState() { return lldb::eStateStepping; }
33+
34+
virtual llvm::Expected<bool> GetStopDescription(lldb_private::Stream *s) {
35+
return true;
36+
}
37+
};
38+
} // namespace lldb_private
39+
40+
#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDTHREADPLANINTERFACE_H

lldb/include/lldb/Interpreter/ScriptInterpreter.h

+12-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"
@@ -25,6 +27,7 @@
2527
#include "lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h"
2628
#include "lldb/Interpreter/Interfaces/ScriptedProcessInterface.h"
2729
#include "lldb/Interpreter/Interfaces/ScriptedThreadInterface.h"
30+
#include "lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h"
2831
#include "lldb/Interpreter/ScriptObject.h"
2932
#include "lldb/Utility/Broadcaster.h"
3033
#include "lldb/Utility/Status.h"
@@ -253,50 +256,6 @@ class ScriptInterpreter : public PluginInterface {
253256
return lldb::ValueObjectListSP();
254257
}
255258

256-
virtual StructuredData::ObjectSP
257-
CreateScriptedThreadPlan(const char *class_name,
258-
const StructuredDataImpl &args_data,
259-
std::string &error_str,
260-
lldb::ThreadPlanSP thread_plan_sp) {
261-
return StructuredData::ObjectSP();
262-
}
263-
264-
virtual bool
265-
ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
266-
Event *event, bool &script_error) {
267-
script_error = true;
268-
return true;
269-
}
270-
271-
virtual bool
272-
ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp,
273-
Event *event, bool &script_error) {
274-
script_error = true;
275-
return true;
276-
}
277-
278-
virtual bool
279-
ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp,
280-
bool &script_error) {
281-
script_error = true;
282-
return true;
283-
}
284-
285-
virtual lldb::StateType
286-
ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp,
287-
bool &script_error) {
288-
script_error = true;
289-
return lldb::eStateStepping;
290-
}
291-
292-
virtual bool
293-
ScriptedThreadPlanGetStopDescription(StructuredData::ObjectSP implementor_sp,
294-
lldb_private::Stream *stream,
295-
bool &script_error) {
296-
script_error = true;
297-
return false;
298-
}
299-
300259
virtual StructuredData::GenericSP
301260
CreateScriptedBreakpointResolver(const char *class_name,
302261
const StructuredDataImpl &args_data,
@@ -566,6 +525,11 @@ class ScriptInterpreter : public PluginInterface {
566525
return std::make_shared<ScriptedThreadInterface>();
567526
}
568527

528+
virtual lldb::ScriptedThreadPlanInterfaceSP
529+
CreateScriptedThreadPlanInterface() {
530+
return std::make_shared<ScriptedThreadPlanInterface>();
531+
}
532+
569533
virtual lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() {
570534
return std::make_shared<OperatingSystemInterface>();
571535
}
@@ -584,6 +548,10 @@ class ScriptInterpreter : public PluginInterface {
584548

585549
Status GetStatusFromSBError(const lldb::SBError &error) const;
586550

551+
Event *GetOpaqueTypeFromSBEvent(const lldb::SBEvent &event) const;
552+
553+
Stream *GetOpaqueTypeFromSBStream(const lldb::SBStream &stream) const;
554+
587555
lldb::BreakpointSP
588556
GetOpaqueTypeFromSBBreakpoint(const lldb::SBBreakpoint &breakpoint) const;
589557

0 commit comments

Comments
 (0)