[lldb/SWIG] Refactor extensions to be non Python-specific (2/2)

The current SWIG extensions for the string conversion operator is Python
specific because it uses the PythonObjects. This means that the code
cannot be reused for other SWIG supported languages such as Lua.

This reimplements the extensions in a more generic way that can be
reused. It uses a SWIG macro to reduce code duplication.

Differential revision: https://reviews.llvm.org/D72377
This commit is contained in:
Jonas Devlieghere
2020-01-08 16:13:03 -08:00
parent 7f1026a752
commit ae47a3d810
25 changed files with 95 additions and 287 deletions

View File

@@ -1,42 +1,4 @@
%extend lldb::SBAddress {
%nothreadallow;
PyObject *lldb::SBAddress::__str__ (){
lldb::SBStream description;
$self->GetDescription (description);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
}
%extend lldb::SBBlock {
%nothreadallow;
PyObject *lldb::SBBlock::__str__ (){
lldb::SBStream description;
$self->GetDescription (description);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
}
%extend lldb::SBBreakpoint {
%nothreadallow;
PyObject *lldb::SBBreakpoint::__str__ (){
lldb::SBStream description;
$self->GetDescription (description);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
%pythoncode %{
def __eq__(self, rhs):
if not isinstance(rhs, type(self)):
@@ -50,34 +12,6 @@
return getattr(_lldb,self.__class__.__name__+"___ne__")(self, rhs)
%}
}
%extend lldb::SBBreakpointLocation {
%nothreadallow;
PyObject *lldb::SBBreakpointLocation::__str__ (){
lldb::SBStream description;
$self->GetDescription (description, lldb::eDescriptionLevelFull);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
}
%extend lldb::SBBreakpointName {
%nothreadallow;
PyObject *lldb::SBBreakpointName::__str__ (){
lldb::SBStream description;
$self->GetDescription (description);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
}
%extend lldb::SBBroadcaster {
@@ -97,18 +31,6 @@
}
%extend lldb::SBCommandReturnObject {
%nothreadallow;
PyObject *lldb::SBCommandReturnObject::__str__ (){
lldb::SBStream description;
$self->GetDescription (description);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
/* the write() and flush() calls are not part of the SB API proper, and are solely for Python usage
they are meant to make an SBCommandReturnObject into a file-like object so that instructions of the sort
print >>sb_command_return_object, "something"
@@ -122,18 +44,8 @@
void lldb::SBCommandReturnObject::flush ()
{}
}
%extend lldb::SBCompileUnit {
%nothreadallow;
PyObject *lldb::SBCompileUnit::__str__ (){
lldb::SBStream description;
$self->GetDescription (description);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
%pythoncode %{
def __eq__(self, rhs):
if not isinstance(rhs, type(self)):
@@ -148,45 +60,8 @@
return getattr(_lldb,self.__class__.__name__+"___ne__")(self, rhs)
%}
}
%extend lldb::SBData {
%nothreadallow;
PyObject *lldb::SBData::__str__ (){
lldb::SBStream description;
$self->GetDescription (description);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
}
%extend lldb::SBDebugger {
%nothreadallow;
PyObject *lldb::SBDebugger::__str__ (){
lldb::SBStream description;
$self->GetDescription (description);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
}
%extend lldb::SBDeclaration {
%nothreadallow;
PyObject *lldb::SBDeclaration::__str__ (){
lldb::SBStream description;
$self->GetDescription (description);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
%pythoncode %{
def __eq__(self, rhs):
if not isinstance(rhs, type(self)):
@@ -200,60 +75,9 @@
return getattr(_lldb,self.__class__.__name__+"___ne__")(self, rhs)
%}
}
}
%extend lldb::SBError {
%nothreadallow;
PyObject *lldb::SBError::__str__ (){
lldb::SBStream description;
$self->GetDescription (description);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
}
%extend lldb::SBFileSpec {
%nothreadallow;
PyObject *lldb::SBFileSpec::__str__ (){
lldb::SBStream description;
$self->GetDescription (description);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
}
%extend lldb::SBFrame {
%nothreadallow;
PyObject *lldb::SBFrame::__str__ (){
lldb::SBStream description;
$self->GetDescription (description);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
}
%extend lldb::SBFunction {
%nothreadallow;
PyObject *lldb::SBFunction::__str__ (){
lldb::SBStream description;
$self->GetDescription (description);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
%pythoncode %{
def __eq__(self, rhs):
if not isinstance(rhs, type(self)):
@@ -267,47 +91,9 @@
return getattr(_lldb,self.__class__.__name__+"___ne__")(self, rhs)
%}
}
}
%extend lldb::SBInstruction {
%nothreadallow;
PyObject *lldb::SBInstruction::__str__ (){
lldb::SBStream description;
$self->GetDescription (description);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
}
%extend lldb::SBInstructionList {
%nothreadallow;
PyObject *lldb::SBInstructionList::__str__ (){
lldb::SBStream description;
$self->GetDescription (description);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
}
%extend lldb::SBLineEntry {
%nothreadallow;
PyObject *lldb::SBLineEntry::__str__ (){
lldb::SBStream description;
$self->GetDescription (description);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
%pythoncode %{
def __eq__(self, rhs):
if not isinstance(rhs, type(self)):
@@ -323,33 +109,7 @@
%}
}
%extend lldb::SBMemoryRegionInfo {
%nothreadallow;
PyObject *lldb::SBMemoryRegionInfo::__str__ (){
lldb::SBStream description;
$self->GetDescription (description);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
}
%extend lldb::SBModule {
%nothreadallow;
PyObject *lldb::SBModule::__str__ (){
lldb::SBStream description;
$self->GetDescription (description);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
%pythoncode %{
def __eq__(self, rhs):
if not isinstance(rhs, type(self)):
@@ -365,34 +125,6 @@
%}
}
%extend lldb::SBModuleSpec {
%nothreadallow;
PyObject *lldb::SBModuleSpec::__str__ (){
lldb::SBStream description;
$self->GetDescription (description);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
}
%extend lldb::SBModuleSpecList {
%nothreadallow;
PyObject *lldb::SBModuleSpecList::__str__ (){
lldb::SBStream description;
$self->GetDescription (description);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return PythonString(llvm::StringRef(desc, desc_len)).release();
}
%clearnothreadallow;
}
%extend lldb::SBProcess {
%nothreadallow;
PyObject *lldb::SBProcess::__str__ (){

View File

@@ -140,6 +140,8 @@ public:
lldb::SBLineEntry
GetLineEntry ();
STRING_EXTENSION(SBAddress)
#ifdef SWIGPYTHON
%pythoncode %{
def __get_load_addr_property__ (self):

View File

@@ -100,6 +100,8 @@ public:
bool locals,
bool statics);
STRING_EXTENSION(SBBlock)
#ifdef SWIGPYTHON
%pythoncode %{
def get_range_at_index(self, idx):

View File

@@ -249,6 +249,8 @@ public:
bool
IsHardware ();
STRING_EXTENSION(SBBreakpoint)
#ifdef SWIGPYTHON
%pythoncode %{

View File

@@ -134,6 +134,8 @@ public:
SBBreakpoint
GetBreakpoint ();
STRING_EXTENSION_LEVEL(SBBreakpointLocation, lldb::eDescriptionLevelFull)
};
} // namespace lldb

View File

@@ -108,6 +108,7 @@ public:
bool GetDescription(lldb::SBStream &description);
STRING_EXTENSION(SBBreakpointName)
};
} // namespace lldb

View File

@@ -96,6 +96,8 @@ public:
void SetImmediateOutputFile(lldb::FileSP BORROWED);
void SetImmediateErrorFile(lldb::FileSP BORROWED);
STRING_EXTENSION(SBCommandReturnObject)
%extend {
// transfer_ownership does nothing, and is here for compatibility with
// old scripts. Ownership is tracked by reference count in the ordinary way.

View File

@@ -116,6 +116,8 @@ public:
bool
operator != (const lldb::SBCompileUnit &rhs) const;
STRING_EXTENSION(SBCompileUnit)
#ifdef SWIGPYTHON
%pythoncode %{
def __iter__(self):

View File

@@ -134,6 +134,8 @@ public:
bool
SetDataFromDoubleArray (double* array, size_t array_len);
STRING_EXTENSION(SBData)
#ifdef SWIGPYTHON
%pythoncode %{

View File

@@ -479,6 +479,8 @@ public:
lldb::SBTypeSynthetic
GetSyntheticForType (lldb::SBTypeNameSpecifier);
STRING_EXTENSION(SBDebugger)
%feature("docstring",
"Launch a command interpreter session. Commands are read from standard input or
from the input handle specified for the debugger object. Output/errors are

View File

@@ -53,6 +53,8 @@ namespace lldb {
bool
operator != (const lldb::SBDeclaration &rhs) const;
STRING_EXTENSION(SBDeclaration)
#ifdef SWIGPYTHON
%pythoncode %{
file = property(GetFileSpec, None, doc='''A read only property that returns an lldb object that represents the file (lldb.SBFileSpec) for this line entry.''')

View File

@@ -105,6 +105,8 @@ public:
bool
GetDescription (lldb::SBStream &description);
STRING_EXTENSION(SBError)
#ifdef SWIGPYTHON
%pythoncode %{
value = property(GetError, None, doc='''A read only property that returns the same result as GetError().''')

View File

@@ -80,6 +80,8 @@ public:
void
AppendPathComponent (const char *file_or_directory);
STRING_EXTENSION(SBFileSpec)
#ifdef SWIGPYTHON
%pythoncode %{
def __get_fullpath__(self):

View File

@@ -285,6 +285,8 @@ public:
bool
GetDescription (lldb::SBStream &description);
STRING_EXTENSION(SBFrame)
#ifdef SWIGPYTHON
%pythoncode %{
def get_all_variables(self):

View File

@@ -111,6 +111,8 @@ public:
bool
operator != (const lldb::SBFunction &rhs) const;
STRING_EXTENSION(SBFunction)
#ifdef SWIGPYTHON
%pythoncode %{
def get_instructions_from_current_target (self):

View File

@@ -74,6 +74,8 @@ public:
bool
TestEmulation (lldb::SBStream &output_stream, const char *test_file);
STRING_EXTENSION(SBInstruction)
#ifdef SWIGPYTHON
%pythoncode %{
def __mnemonic_property__ (self):

View File

@@ -66,6 +66,8 @@ public:
bool
DumpEmulationForAllInstructions (const char *triple);
STRING_EXTENSION(SBInstructionList)
#ifdef SWIGPYTHON
%pythoncode %{
def __iter__(self):

View File

@@ -84,6 +84,8 @@ public:
bool
operator != (const lldb::SBLineEntry &rhs) const;
STRING_EXTENSION(SBLineEntry)
#ifdef SWIGPYTHON
%pythoncode %{
file = property(GetFileSpec, None, doc='''A read only property that returns an lldb object that represents the file (lldb.SBFileSpec) for this line entry.''')

View File

@@ -55,6 +55,7 @@ public:
bool
GetDescription (lldb::SBStream &description);
STRING_EXTENSION(SBMemoryRegionInfo)
};
} // namespace lldb

View File

@@ -344,6 +344,8 @@ public:
lldb::SBAddress
GetObjectFileEntryPointAddress() const;
STRING_EXTENSION(SBModule)
#ifdef SWIGPYTHON
%pythoncode %{
def __len__(self):

View File

@@ -91,6 +91,7 @@ public:
bool
GetDescription (lldb::SBStream &description);
STRING_EXTENSION(SBModuleSpec)
};
@@ -127,6 +128,7 @@ public:
bool
GetDescription (lldb::SBStream &description);
STRING_EXTENSION(SBModuleSpecList)
};
} // namespace lldb

View File

@@ -967,21 +967,7 @@ public:
lldb::SBValue
EvaluateExpression (const char *expr, const lldb::SBExpressionOptions &options);
%extend {
%nothreadallow;
std::string lldb::SBTarget::__str__(){
lldb::SBStream stream;
$self->GetDescription (stream, lldb::eDescriptionLevelBrief);
const char *desc = stream.GetData();
size_t desc_len = stream.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
return std::string(desc, desc_len);
}
%clearnothreadallow;
}
STRING_EXTENSION_LEVEL(SBTarget, lldb::eDescriptionLevelBrief)
#ifdef SWIGPYTHON
%pythoncode %{

View File

@@ -59,6 +59,23 @@ except ImportError:
// Parameter types will be used in the autodoc string.
%feature("autodoc", "1");
%define ARRAYHELPER(type,name)
%inline %{
type *new_ ## name (int nitems) {
return (type *) malloc(sizeof(type)*nitems);
}
void delete_ ## name(type *t) {
free(t);
}
type name ## _get(type *t, int index) {
return t[index];
}
void name ## _set(type *t, int index, type val) {
t[index] = val;
}
%}
%enddef
%pythoncode%{
import uuid
import re
@@ -95,6 +112,7 @@ def lldb_iter(obj, getsize, getelem):
%include <std_string.i>
%include "./Python/python-typemaps.swig"
%include "./macros.swig"
%include "./headers.swig"
%{

View File

@@ -9,6 +9,7 @@
%module lldb
%include <std_string.i>
%include "./macros.swig"
%include "./headers.swig"
%{

33
lldb/scripts/macros.swig Normal file
View File

@@ -0,0 +1,33 @@
%define STRING_EXTENSION_LEVEL(Class, Level)
%extend {
%nothreadallow;
std::string lldb:: ## Class ## ::__str__(){
lldb::SBStream stream;
$self->GetDescription (stream, Level);
const char *desc = stream.GetData();
size_t desc_len = stream.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == 'n' || desc[desc_len-1] == 'r')) {
--desc_len;
}
return std::string(desc, desc_len);
}
%clearnothreadallow;
}
%enddef
%define STRING_EXTENSION(Class)
%extend {
%nothreadallow;
std::string lldb:: ## Class ## ::__str__(){
lldb::SBStream stream;
$self->GetDescription (stream);
const char *desc = stream.GetData();
size_t desc_len = stream.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == 'n' || desc[desc_len-1] == 'r')) {
--desc_len;
}
return std::string(desc, desc_len);
}
%clearnothreadallow;
}
%enddef