106c3fb27SDimitry Andric/* Typemap definitions, to allow SWIG to properly handle 'char**' data types. 206c3fb27SDimitry Andric 306c3fb27SDimitry AndricNOTE: If there's logic to free memory in a %typemap(freearg), it will also be 406c3fb27SDimitry Andricrun if you call SWIG_fail on an error path. Don't manually free() an argument 506c3fb27SDimitry AndricAND call SWIG_fail at the same time, because it will result in a double free. 606c3fb27SDimitry Andric 706c3fb27SDimitry Andric*/ 8130d950cSDimitry Andric 9e8d8bef9SDimitry Andric%inline %{ 10e8d8bef9SDimitry Andric 11e8d8bef9SDimitry Andric#include "../bindings/python/python-typemaps.h" 12e8d8bef9SDimitry Andric 13e8d8bef9SDimitry Andric%} 14e8d8bef9SDimitry Andric 15130d950cSDimitry Andric%typemap(in) char ** { 16130d950cSDimitry Andric /* Check if is a list */ 17130d950cSDimitry Andric if (PythonList::Check($input)) { 18130d950cSDimitry Andric PythonList list(PyRefType::Borrowed, $input); 19130d950cSDimitry Andric int size = list.GetSize(); 20130d950cSDimitry Andric int i = 0; 21130d950cSDimitry Andric $1 = (char **)malloc((size + 1) * sizeof(char *)); 22130d950cSDimitry Andric for (i = 0; i < size; i++) { 23130d950cSDimitry Andric PythonString py_str = list.GetItemAtIndex(i).AsType<PythonString>(); 24130d950cSDimitry Andric if (!py_str.IsAllocated()) { 25130d950cSDimitry Andric PyErr_SetString(PyExc_TypeError, "list must contain strings"); 26bdd1243dSDimitry Andric SWIG_fail; 27130d950cSDimitry Andric } 28130d950cSDimitry Andric 29130d950cSDimitry Andric $1[i] = const_cast<char *>(py_str.GetString().data()); 30130d950cSDimitry Andric } 31130d950cSDimitry Andric $1[i] = 0; 32130d950cSDimitry Andric } else if ($input == Py_None) { 33130d950cSDimitry Andric $1 = NULL; 34130d950cSDimitry Andric } else { 35130d950cSDimitry Andric PyErr_SetString(PyExc_TypeError, "not a list"); 36bdd1243dSDimitry Andric SWIG_fail; 37130d950cSDimitry Andric } 38130d950cSDimitry Andric} 39130d950cSDimitry Andric 40130d950cSDimitry Andric%typemap(typecheck) char ** { 41130d950cSDimitry Andric /* Check if is a list */ 42130d950cSDimitry Andric $1 = 1; 43130d950cSDimitry Andric if (PythonList::Check($input)) { 44130d950cSDimitry Andric PythonList list(PyRefType::Borrowed, $input); 45130d950cSDimitry Andric int size = list.GetSize(); 46130d950cSDimitry Andric int i = 0; 47130d950cSDimitry Andric for (i = 0; i < size; i++) { 48130d950cSDimitry Andric PythonString s = list.GetItemAtIndex(i).AsType<PythonString>(); 490eae32dcSDimitry Andric if (!s.IsAllocated()) { 500eae32dcSDimitry Andric $1 = 0; 51130d950cSDimitry Andric } 52130d950cSDimitry Andric } 530eae32dcSDimitry Andric } else { 54130d950cSDimitry Andric $1 = (($input == Py_None) ? 1 : 0); 55130d950cSDimitry Andric } 56130d950cSDimitry Andric} 57130d950cSDimitry Andric 58130d950cSDimitry Andric%typemap(freearg) char** { 59130d950cSDimitry Andric free((char *) $1); 60130d950cSDimitry Andric} 61130d950cSDimitry Andric 6206c3fb27SDimitry Andric%typecheck(SWIG_TYPECHECK_POINTER) lldb::ScriptObjectPtr { 6306c3fb27SDimitry Andric PythonObject obj(PyRefType::Borrowed, $input); 6406c3fb27SDimitry Andric if (!obj.IsValid()) { 6506c3fb27SDimitry Andric PyErr_Clear(); 6606c3fb27SDimitry Andric $1 = 0; 6706c3fb27SDimitry Andric } else { 6806c3fb27SDimitry Andric $1 = 1; 6906c3fb27SDimitry Andric } 7006c3fb27SDimitry Andric} 7106c3fb27SDimitry Andric 7206c3fb27SDimitry Andric%typemap(in) lldb::ScriptObjectPtr { 7306c3fb27SDimitry Andric if ($input == Py_None) { 7406c3fb27SDimitry Andric $1 = nullptr; 7506c3fb27SDimitry Andric } else { 7606c3fb27SDimitry Andric PythonObject obj(PyRefType::Borrowed, $input); 7706c3fb27SDimitry Andric if (!obj.IsValid()) { 7806c3fb27SDimitry Andric PyErr_SetString(PyExc_TypeError, "Script object is not valid"); 7906c3fb27SDimitry Andric SWIG_fail; 8006c3fb27SDimitry Andric } 8106c3fb27SDimitry Andric 8206c3fb27SDimitry Andric auto lldb_module = PythonModule::Import("lldb"); 8306c3fb27SDimitry Andric if (!lldb_module) { 8406c3fb27SDimitry Andric std::string err_msg = llvm::toString(lldb_module.takeError()); 8506c3fb27SDimitry Andric PyErr_SetString(PyExc_TypeError, err_msg.c_str()); 8606c3fb27SDimitry Andric SWIG_fail; 8706c3fb27SDimitry Andric } 8806c3fb27SDimitry Andric 8906c3fb27SDimitry Andric auto sb_structured_data_class = lldb_module.get().Get("SBStructuredData"); 9006c3fb27SDimitry Andric if (!sb_structured_data_class) { 9106c3fb27SDimitry Andric std::string err_msg = llvm::toString(sb_structured_data_class.takeError()); 9206c3fb27SDimitry Andric PyErr_SetString(PyExc_TypeError, err_msg.c_str()); 9306c3fb27SDimitry Andric SWIG_fail; 9406c3fb27SDimitry Andric } 9506c3fb27SDimitry Andric 9606c3fb27SDimitry Andric if (obj.IsInstance(sb_structured_data_class.get())) { 9706c3fb27SDimitry Andric $1 = obj.get(); 9806c3fb27SDimitry Andric } else { 9906c3fb27SDimitry Andric auto type = obj.GetType(); 10006c3fb27SDimitry Andric if (!type) { 10106c3fb27SDimitry Andric std::string err_msg = llvm::toString(type.takeError()); 10206c3fb27SDimitry Andric PyErr_SetString(PyExc_TypeError, err_msg.c_str()); 10306c3fb27SDimitry Andric SWIG_fail; 10406c3fb27SDimitry Andric } 10506c3fb27SDimitry Andric 10606c3fb27SDimitry Andric auto type_name = As<std::string>(type.get().GetAttribute("__name__")); 10706c3fb27SDimitry Andric if (!type_name) { 10806c3fb27SDimitry Andric std::string err_msg = llvm::toString(type_name.takeError()); 10906c3fb27SDimitry Andric PyErr_SetString(PyExc_TypeError, err_msg.c_str()); 11006c3fb27SDimitry Andric SWIG_fail; 11106c3fb27SDimitry Andric } 11206c3fb27SDimitry Andric 113*cb14a3feSDimitry Andric if (llvm::StringRef(type_name.get()).starts_with("SB")) { 11406c3fb27SDimitry Andric std::string error_msg = "Input type is invalid: " + type_name.get(); 11506c3fb27SDimitry Andric PyErr_SetString(PyExc_TypeError, error_msg.c_str()); 11606c3fb27SDimitry Andric SWIG_fail; 11706c3fb27SDimitry Andric } else { 11806c3fb27SDimitry Andric $1 = obj.get(); 11906c3fb27SDimitry Andric } 12006c3fb27SDimitry Andric } 12106c3fb27SDimitry Andric } 12206c3fb27SDimitry Andric} 12306c3fb27SDimitry Andric 12406c3fb27SDimitry Andric%typemap(out) lldb::ScriptObjectPtr { 12506c3fb27SDimitry Andric $result = (PyObject*) $1; 12606c3fb27SDimitry Andric if (!$result) 12706c3fb27SDimitry Andric $result = Py_None; 12806c3fb27SDimitry Andric Py_INCREF($result); 12906c3fb27SDimitry Andric} 13006c3fb27SDimitry Andric 13106c3fb27SDimitry Andric%typemap(out) lldb::SBScriptObject { 13206c3fb27SDimitry Andric $result = nullptr; 13306c3fb27SDimitry Andric if (const void* impl = $1.GetPointer()) 13406c3fb27SDimitry Andric $result = (PyObject*) impl; 13506c3fb27SDimitry Andric if (!$result) { 13606c3fb27SDimitry Andric $result = Py_None; 13706c3fb27SDimitry Andric Py_INCREF(Py_None); 13806c3fb27SDimitry Andric } else { 13906c3fb27SDimitry Andric Py_INCREF($result); 14006c3fb27SDimitry Andric } 14106c3fb27SDimitry Andric} 14206c3fb27SDimitry Andric 143130d950cSDimitry Andric%typemap(out) char** { 144130d950cSDimitry Andric int len; 145130d950cSDimitry Andric int i; 146130d950cSDimitry Andric len = 0; 1470eae32dcSDimitry Andric while ($1[len]) 1480eae32dcSDimitry Andric len++; 149130d950cSDimitry Andric PythonList list(len); 150130d950cSDimitry Andric for (i = 0; i < len; i++) 151130d950cSDimitry Andric list.SetItemAtIndex(i, PythonString($1[i])); 152130d950cSDimitry Andric $result = list.release(); 153130d950cSDimitry Andric} 154130d950cSDimitry Andric 155130d950cSDimitry Andric%typemap(in) lldb::tid_t { 1565ffd83dbSDimitry Andric PythonObject obj = Retain<PythonObject>($input); 1575ffd83dbSDimitry Andric lldb::tid_t value = unwrapOrSetPythonException(As<unsigned long long>(obj)); 1585ffd83dbSDimitry Andric if (PyErr_Occurred()) 159bdd1243dSDimitry Andric SWIG_fail; 1605ffd83dbSDimitry Andric $1 = value; 161130d950cSDimitry Andric} 162130d950cSDimitry Andric 163130d950cSDimitry Andric%typemap(in) lldb::StateType { 1645ffd83dbSDimitry Andric PythonObject obj = Retain<PythonObject>($input); 1655ffd83dbSDimitry Andric unsigned long long state_type_value = 1665ffd83dbSDimitry Andric unwrapOrSetPythonException(As<unsigned long long>(obj)); 1675ffd83dbSDimitry Andric if (PyErr_Occurred()) 168bdd1243dSDimitry Andric SWIG_fail; 169130d950cSDimitry Andric if (state_type_value > lldb::StateType::kLastStateType) { 170130d950cSDimitry Andric PyErr_SetString(PyExc_ValueError, "Not a valid StateType value"); 171bdd1243dSDimitry Andric SWIG_fail; 172130d950cSDimitry Andric } 173130d950cSDimitry Andric $1 = static_cast<lldb::StateType>(state_type_value); 174130d950cSDimitry Andric} 175130d950cSDimitry Andric 176130d950cSDimitry Andric/* Typemap definitions to allow SWIG to properly handle char buffer. */ 177130d950cSDimitry Andric 178130d950cSDimitry Andric// typemap for a char buffer 179130d950cSDimitry Andric%typemap(in) (char *dst, size_t dst_len) { 18006c3fb27SDimitry Andric if (!PyLong_Check($input)) { 181130d950cSDimitry Andric PyErr_SetString(PyExc_ValueError, "Expecting an integer"); 182bdd1243dSDimitry Andric SWIG_fail; 183130d950cSDimitry Andric } 18406c3fb27SDimitry Andric $2 = PyLong_AsLong($input); 185130d950cSDimitry Andric if ($2 <= 0) { 186130d950cSDimitry Andric PyErr_SetString(PyExc_ValueError, "Positive integer expected"); 187bdd1243dSDimitry Andric SWIG_fail; 188130d950cSDimitry Andric } 189130d950cSDimitry Andric $1 = (char *)malloc($2); 190130d950cSDimitry Andric} 191130d950cSDimitry Andric// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated 192130d950cSDimitry Andric// as char data instead of byte data. 193130d950cSDimitry Andric%typemap(in) (void *char_buf, size_t size) = (char *dst, size_t dst_len); 194130d950cSDimitry Andric 195130d950cSDimitry Andric// Return the char buffer. Discarding any previous return result 196130d950cSDimitry Andric%typemap(argout) (char *dst, size_t dst_len) { 197130d950cSDimitry Andric Py_XDECREF($result); /* Blow away any previous result */ 198130d950cSDimitry Andric if (result == 0) { 199130d950cSDimitry Andric PythonString string(""); 200130d950cSDimitry Andric $result = string.release(); 201130d950cSDimitry Andric Py_INCREF($result); 202130d950cSDimitry Andric } else { 203130d950cSDimitry Andric llvm::StringRef ref(static_cast<const char *>($1), result); 204130d950cSDimitry Andric PythonString string(ref); 205130d950cSDimitry Andric $result = string.release(); 206130d950cSDimitry Andric } 207130d950cSDimitry Andric free($1); 208130d950cSDimitry Andric} 209130d950cSDimitry Andric// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated 210130d950cSDimitry Andric// as char data instead of byte data. 211130d950cSDimitry Andric%typemap(argout) (void *char_buf, size_t size) = (char *dst, size_t dst_len); 212130d950cSDimitry Andric 213130d950cSDimitry Andric 214130d950cSDimitry Andric// typemap for handling an snprintf-like API like SBThread::GetStopDescription. 215130d950cSDimitry Andric%typemap(in) (char *dst_or_null, size_t dst_len) { 21606c3fb27SDimitry Andric if (!PyLong_Check($input)) { 217130d950cSDimitry Andric PyErr_SetString(PyExc_ValueError, "Expecting an integer"); 218bdd1243dSDimitry Andric SWIG_fail; 219130d950cSDimitry Andric } 22006c3fb27SDimitry Andric $2 = PyLong_AsLong($input); 221130d950cSDimitry Andric if ($2 <= 0) { 222130d950cSDimitry Andric PyErr_SetString(PyExc_ValueError, "Positive integer expected"); 223bdd1243dSDimitry Andric SWIG_fail; 224130d950cSDimitry Andric } 225130d950cSDimitry Andric $1 = (char *)malloc($2); 226130d950cSDimitry Andric} 227130d950cSDimitry Andric%typemap(argout) (char *dst_or_null, size_t dst_len) { 228130d950cSDimitry Andric Py_XDECREF($result); /* Blow away any previous result */ 229130d950cSDimitry Andric llvm::StringRef ref($1); 230130d950cSDimitry Andric PythonString string(ref); 231130d950cSDimitry Andric $result = string.release(); 232130d950cSDimitry Andric free($1); 233130d950cSDimitry Andric} 234130d950cSDimitry Andric 235130d950cSDimitry Andric 236130d950cSDimitry Andric// typemap for an outgoing buffer 237130d950cSDimitry Andric// See also SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len). 238130d950cSDimitry Andric// Ditto for SBProcess::PutSTDIN(const char *src, size_t src_len). 239130d950cSDimitry Andric%typemap(in) (const char *cstr, uint32_t cstr_len), 240130d950cSDimitry Andric (const char *src, size_t src_len) { 241130d950cSDimitry Andric if (PythonString::Check($input)) { 242130d950cSDimitry Andric PythonString str(PyRefType::Borrowed, $input); 243130d950cSDimitry Andric $1 = (char *)str.GetString().data(); 244130d950cSDimitry Andric $2 = str.GetSize(); 2450eae32dcSDimitry Andric } else if (PythonByteArray::Check($input)) { 246130d950cSDimitry Andric PythonByteArray bytearray(PyRefType::Borrowed, $input); 247130d950cSDimitry Andric $1 = (char *)bytearray.GetBytes().data(); 248130d950cSDimitry Andric $2 = bytearray.GetSize(); 2490eae32dcSDimitry Andric } else if (PythonBytes::Check($input)) { 250130d950cSDimitry Andric PythonBytes bytes(PyRefType::Borrowed, $input); 251130d950cSDimitry Andric $1 = (char *)bytes.GetBytes().data(); 252130d950cSDimitry Andric $2 = bytes.GetSize(); 2530eae32dcSDimitry Andric } else { 254130d950cSDimitry Andric PyErr_SetString(PyExc_ValueError, "Expecting a string"); 255bdd1243dSDimitry Andric SWIG_fail; 256130d950cSDimitry Andric } 257130d950cSDimitry Andric} 258130d950cSDimitry Andric// For SBProcess::WriteMemory, SBTarget::GetInstructions and SBDebugger::DispatchInput. 259130d950cSDimitry Andric%typemap(in) (const void *buf, size_t size), 260130d950cSDimitry Andric (const void *data, size_t data_len) { 261130d950cSDimitry Andric if (PythonString::Check($input)) { 262130d950cSDimitry Andric PythonString str(PyRefType::Borrowed, $input); 263130d950cSDimitry Andric $1 = (void *)str.GetString().data(); 264130d950cSDimitry Andric $2 = str.GetSize(); 2650eae32dcSDimitry Andric } else if (PythonByteArray::Check($input)) { 266130d950cSDimitry Andric PythonByteArray bytearray(PyRefType::Borrowed, $input); 267130d950cSDimitry Andric $1 = (void *)bytearray.GetBytes().data(); 268130d950cSDimitry Andric $2 = bytearray.GetSize(); 2690eae32dcSDimitry Andric } else if (PythonBytes::Check($input)) { 270130d950cSDimitry Andric PythonBytes bytes(PyRefType::Borrowed, $input); 271130d950cSDimitry Andric $1 = (void *)bytes.GetBytes().data(); 272130d950cSDimitry Andric $2 = bytes.GetSize(); 2730eae32dcSDimitry Andric } else { 274130d950cSDimitry Andric PyErr_SetString(PyExc_ValueError, "Expecting a buffer"); 275bdd1243dSDimitry Andric SWIG_fail; 276130d950cSDimitry Andric } 277130d950cSDimitry Andric} 278130d950cSDimitry Andric 279130d950cSDimitry Andric// typemap for an incoming buffer 280130d950cSDimitry Andric// See also SBProcess::ReadMemory. 281130d950cSDimitry Andric%typemap(in) (void *buf, size_t size) { 28206c3fb27SDimitry Andric if (PyLong_Check($input)) { 283130d950cSDimitry Andric $2 = PyLong_AsLong($input); 284130d950cSDimitry Andric } else { 285130d950cSDimitry Andric PyErr_SetString(PyExc_ValueError, "Expecting an integer or long object"); 286bdd1243dSDimitry Andric SWIG_fail; 287130d950cSDimitry Andric } 288130d950cSDimitry Andric if ($2 <= 0) { 289130d950cSDimitry Andric PyErr_SetString(PyExc_ValueError, "Positive integer expected"); 290bdd1243dSDimitry Andric SWIG_fail; 291130d950cSDimitry Andric } 292130d950cSDimitry Andric $1 = (void *)malloc($2); 293130d950cSDimitry Andric} 294130d950cSDimitry Andric 295130d950cSDimitry Andric// Return the buffer. Discarding any previous return result 296130d950cSDimitry Andric// See also SBProcess::ReadMemory. 297130d950cSDimitry Andric%typemap(argout) (void *buf, size_t size) { 298130d950cSDimitry Andric Py_XDECREF($result); /* Blow away any previous result */ 299130d950cSDimitry Andric if (result == 0) { 300130d950cSDimitry Andric $result = Py_None; 301130d950cSDimitry Andric Py_INCREF($result); 302130d950cSDimitry Andric } else { 303130d950cSDimitry Andric PythonBytes bytes(static_cast<const uint8_t *>($1), result); 304130d950cSDimitry Andric $result = bytes.release(); 305130d950cSDimitry Andric } 306130d950cSDimitry Andric free($1); 307130d950cSDimitry Andric} 308130d950cSDimitry Andric 309130d950cSDimitry Andric%{ 310130d950cSDimitry Andricnamespace { 311130d950cSDimitry Andrictemplate <class T> 312130d950cSDimitry AndricT PyLongAsT(PyObject *obj) { 313130d950cSDimitry Andric static_assert(true, "unsupported type"); 314130d950cSDimitry Andric} 315130d950cSDimitry Andric 316130d950cSDimitry Andrictemplate <> uint64_t PyLongAsT<uint64_t>(PyObject *obj) { 317130d950cSDimitry Andric return static_cast<uint64_t>(PyLong_AsUnsignedLongLong(obj)); 318130d950cSDimitry Andric} 319130d950cSDimitry Andric 320130d950cSDimitry Andrictemplate <> uint32_t PyLongAsT<uint32_t>(PyObject *obj) { 321130d950cSDimitry Andric return static_cast<uint32_t>(PyLong_AsUnsignedLong(obj)); 322130d950cSDimitry Andric} 323130d950cSDimitry Andric 324130d950cSDimitry Andrictemplate <> int64_t PyLongAsT<int64_t>(PyObject *obj) { 325130d950cSDimitry Andric return static_cast<int64_t>(PyLong_AsLongLong(obj)); 326130d950cSDimitry Andric} 327130d950cSDimitry Andric 328130d950cSDimitry Andrictemplate <> int32_t PyLongAsT<int32_t>(PyObject *obj) { 329130d950cSDimitry Andric return static_cast<int32_t>(PyLong_AsLong(obj)); 330130d950cSDimitry Andric} 331130d950cSDimitry Andric 3320eae32dcSDimitry Andrictemplate <class T> bool SetNumberFromPyObject(T &number, PyObject *obj) { 33306c3fb27SDimitry Andric if (PyLong_Check(obj)) 334130d950cSDimitry Andric number = PyLongAsT<T>(obj); 3350eae32dcSDimitry Andric else 3360eae32dcSDimitry Andric return false; 337130d950cSDimitry Andric 338130d950cSDimitry Andric return true; 339130d950cSDimitry Andric} 340130d950cSDimitry Andric 3410eae32dcSDimitry Andrictemplate <> bool SetNumberFromPyObject<double>(double &number, PyObject *obj) { 342130d950cSDimitry Andric if (PyFloat_Check(obj)) { 343130d950cSDimitry Andric number = PyFloat_AsDouble(obj); 344130d950cSDimitry Andric return true; 345130d950cSDimitry Andric } 346130d950cSDimitry Andric 347130d950cSDimitry Andric return false; 348130d950cSDimitry Andric} 349130d950cSDimitry Andric 350130d950cSDimitry Andric} // namespace 351130d950cSDimitry Andric%} 352130d950cSDimitry Andric 353130d950cSDimitry Andric// these typemaps allow Python users to pass list objects 354130d950cSDimitry Andric// and have them turn into C++ arrays (this is useful, for instance 355130d950cSDimitry Andric// when creating SBData objects from lists of numbers) 356130d950cSDimitry Andric%typemap(in) (uint64_t* array, size_t array_len), 357130d950cSDimitry Andric (uint32_t* array, size_t array_len), 358130d950cSDimitry Andric (int64_t* array, size_t array_len), 359130d950cSDimitry Andric (int32_t* array, size_t array_len), 360130d950cSDimitry Andric (double* array, size_t array_len) { 361130d950cSDimitry Andric /* Check if is a list */ 362130d950cSDimitry Andric if (PyList_Check($input)) { 363130d950cSDimitry Andric int size = PyList_Size($input); 364130d950cSDimitry Andric int i = 0; 365130d950cSDimitry Andric $2 = size; 366130d950cSDimitry Andric $1 = ($1_type)malloc(size * sizeof($*1_type)); 367130d950cSDimitry Andric for (i = 0; i < size; i++) { 368130d950cSDimitry Andric PyObject *o = PyList_GetItem($input, i); 369130d950cSDimitry Andric if (!SetNumberFromPyObject($1[i], o)) { 370130d950cSDimitry Andric PyErr_SetString(PyExc_TypeError, "list must contain numbers"); 371bdd1243dSDimitry Andric SWIG_fail; 372130d950cSDimitry Andric } 373130d950cSDimitry Andric 374130d950cSDimitry Andric if (PyErr_Occurred()) { 375bdd1243dSDimitry Andric SWIG_fail; 376130d950cSDimitry Andric } 377130d950cSDimitry Andric } 378130d950cSDimitry Andric } else if ($input == Py_None) { 379130d950cSDimitry Andric $1 = NULL; 380130d950cSDimitry Andric $2 = 0; 381130d950cSDimitry Andric } else { 382130d950cSDimitry Andric PyErr_SetString(PyExc_TypeError, "not a list"); 383bdd1243dSDimitry Andric SWIG_fail; 384130d950cSDimitry Andric } 385130d950cSDimitry Andric} 386130d950cSDimitry Andric 387130d950cSDimitry Andric%typemap(freearg) (uint64_t* array, size_t array_len), 388130d950cSDimitry Andric (uint32_t* array, size_t array_len), 389130d950cSDimitry Andric (int64_t* array, size_t array_len), 390130d950cSDimitry Andric (int32_t* array, size_t array_len), 391130d950cSDimitry Andric (double* array, size_t array_len) { 392130d950cSDimitry Andric free($1); 393130d950cSDimitry Andric} 394130d950cSDimitry Andric 395130d950cSDimitry Andric// these typemaps wrap SBModule::GetVersion() from requiring a memory buffer 396130d950cSDimitry Andric// to the more Pythonic style where a list is returned and no previous allocation 397130d950cSDimitry Andric// is necessary - this will break if more than 50 versions are ever returned 398130d950cSDimitry Andric%typemap(typecheck) (uint32_t *versions, uint32_t num_versions) { 399130d950cSDimitry Andric $1 = ($input == Py_None ? 1 : 0); 400130d950cSDimitry Andric} 401130d950cSDimitry Andric 402130d950cSDimitry Andric%typemap(in, numinputs=0) (uint32_t *versions) { 403130d950cSDimitry Andric $1 = (uint32_t *)malloc(sizeof(uint32_t) * 50); 404130d950cSDimitry Andric} 405130d950cSDimitry Andric 406130d950cSDimitry Andric%typemap(in, numinputs=0) (uint32_t num_versions) { 407130d950cSDimitry Andric $1 = 50; 408130d950cSDimitry Andric} 409130d950cSDimitry Andric 410130d950cSDimitry Andric%typemap(argout) (uint32_t *versions, uint32_t num_versions) { 411130d950cSDimitry Andric uint32_t count = result; 412130d950cSDimitry Andric if (count >= $2) 413130d950cSDimitry Andric count = $2; 414130d950cSDimitry Andric PyObject *list = PyList_New(count); 4150eae32dcSDimitry Andric for (uint32_t j = 0; j < count; j++) { 41606c3fb27SDimitry Andric PyObject *item = PyLong_FromLong($1[j]); 417130d950cSDimitry Andric int ok = PyList_SetItem(list, j, item); 4180eae32dcSDimitry Andric if (ok != 0) { 419130d950cSDimitry Andric $result = Py_None; 420130d950cSDimitry Andric break; 421130d950cSDimitry Andric } 422130d950cSDimitry Andric } 423130d950cSDimitry Andric $result = list; 424130d950cSDimitry Andric} 425130d950cSDimitry Andric 426130d950cSDimitry Andric%typemap(freearg) (uint32_t *versions) { 427130d950cSDimitry Andric free($1); 428130d950cSDimitry Andric} 429130d950cSDimitry Andric 430130d950cSDimitry Andric 431130d950cSDimitry Andric// For Log::LogOutputCallback 432130d950cSDimitry Andric%typemap(in) (lldb::LogOutputCallback log_callback, void *baton) { 4330eae32dcSDimitry Andric if (!($input == Py_None || 4340eae32dcSDimitry Andric PyCallable_Check(reinterpret_cast<PyObject *>($input)))) { 435130d950cSDimitry Andric PyErr_SetString(PyExc_TypeError, "Need a callable object or None!"); 436bdd1243dSDimitry Andric SWIG_fail; 437130d950cSDimitry Andric } 438130d950cSDimitry Andric 439130d950cSDimitry Andric // FIXME (filcab): We can't currently check if our callback is already 440130d950cSDimitry Andric // LLDBSwigPythonCallPythonLogOutputCallback (to DECREF the previous 441130d950cSDimitry Andric // baton) nor can we just remove all traces of a callback, if we want to 442130d950cSDimitry Andric // revert to a file logging mechanism. 443130d950cSDimitry Andric 444130d950cSDimitry Andric // Don't lose the callback reference 445130d950cSDimitry Andric Py_INCREF($input); 446130d950cSDimitry Andric $1 = LLDBSwigPythonCallPythonLogOutputCallback; 447130d950cSDimitry Andric $2 = $input; 448130d950cSDimitry Andric} 449130d950cSDimitry Andric 450130d950cSDimitry Andric%typemap(typecheck) (lldb::LogOutputCallback log_callback, void *baton) { 451130d950cSDimitry Andric $1 = $input == Py_None; 452130d950cSDimitry Andric $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input)); 453130d950cSDimitry Andric} 454130d950cSDimitry Andric 45506c3fb27SDimitry Andric// For lldb::SBDebuggerDestroyCallback 45606c3fb27SDimitry Andric%typemap(in) (lldb::SBDebuggerDestroyCallback destroy_callback, void *baton) { 45706c3fb27SDimitry Andric if (!($input == Py_None || 45806c3fb27SDimitry Andric PyCallable_Check(reinterpret_cast<PyObject *>($input)))) { 45906c3fb27SDimitry Andric PyErr_SetString(PyExc_TypeError, "Need a callable object or None!"); 46006c3fb27SDimitry Andric SWIG_fail; 46106c3fb27SDimitry Andric } 46206c3fb27SDimitry Andric 46306c3fb27SDimitry Andric // FIXME (filcab): We can't currently check if our callback is already 46406c3fb27SDimitry Andric // LLDBSwigPythonCallPythonSBDebuggerTerminateCallback (to DECREF the previous 46506c3fb27SDimitry Andric // baton) nor can we just remove all traces of a callback, if we want to 46606c3fb27SDimitry Andric // revert to a file logging mechanism. 46706c3fb27SDimitry Andric 46806c3fb27SDimitry Andric // Don't lose the callback reference 46906c3fb27SDimitry Andric Py_INCREF($input); 47006c3fb27SDimitry Andric $1 = LLDBSwigPythonCallPythonSBDebuggerTerminateCallback; 47106c3fb27SDimitry Andric $2 = $input; 47206c3fb27SDimitry Andric} 47306c3fb27SDimitry Andric 47406c3fb27SDimitry Andric%typemap(typecheck) (lldb::SBDebuggerDestroyCallback destroy_callback, void *baton) { 47506c3fb27SDimitry Andric $1 = $input == Py_None; 47606c3fb27SDimitry Andric $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input)); 47706c3fb27SDimitry Andric} 478130d950cSDimitry Andric 479130d950cSDimitry Andric%typemap(in) lldb::FileSP { 480130d950cSDimitry Andric PythonFile py_file(PyRefType::Borrowed, $input); 481130d950cSDimitry Andric if (!py_file) { 482130d950cSDimitry Andric PyErr_SetString(PyExc_TypeError, "not a file"); 483bdd1243dSDimitry Andric SWIG_fail; 484130d950cSDimitry Andric } 485130d950cSDimitry Andric auto sp = unwrapOrSetPythonException(py_file.ConvertToFile()); 486130d950cSDimitry Andric if (!sp) 487bdd1243dSDimitry Andric SWIG_fail; 488130d950cSDimitry Andric $1 = sp; 489130d950cSDimitry Andric} 490130d950cSDimitry Andric 491130d950cSDimitry Andric%typemap(in) lldb::FileSP FORCE_IO_METHODS { 492130d950cSDimitry Andric PythonFile py_file(PyRefType::Borrowed, $input); 493130d950cSDimitry Andric if (!py_file) { 494130d950cSDimitry Andric PyErr_SetString(PyExc_TypeError, "not a file"); 495bdd1243dSDimitry Andric SWIG_fail; 496130d950cSDimitry Andric } 4970eae32dcSDimitry Andric auto sp = unwrapOrSetPythonException( 4980eae32dcSDimitry Andric py_file.ConvertToFileForcingUseOfScriptingIOMethods()); 499130d950cSDimitry Andric if (!sp) 500bdd1243dSDimitry Andric SWIG_fail; 501130d950cSDimitry Andric $1 = sp; 502130d950cSDimitry Andric} 503130d950cSDimitry Andric 504130d950cSDimitry Andric%typemap(in) lldb::FileSP BORROWED { 505130d950cSDimitry Andric PythonFile py_file(PyRefType::Borrowed, $input); 506130d950cSDimitry Andric if (!py_file) { 507130d950cSDimitry Andric PyErr_SetString(PyExc_TypeError, "not a file"); 508bdd1243dSDimitry Andric SWIG_fail; 509130d950cSDimitry Andric } 5100eae32dcSDimitry Andric auto sp = 5110eae32dcSDimitry Andric unwrapOrSetPythonException(py_file.ConvertToFile(/*borrowed=*/true)); 512130d950cSDimitry Andric if (!sp) 513bdd1243dSDimitry Andric SWIG_fail; 514130d950cSDimitry Andric $1 = sp; 515130d950cSDimitry Andric} 516130d950cSDimitry Andric 517130d950cSDimitry Andric%typemap(in) lldb::FileSP BORROWED_FORCE_IO_METHODS { 518130d950cSDimitry Andric PythonFile py_file(PyRefType::Borrowed, $input); 519130d950cSDimitry Andric if (!py_file) { 520130d950cSDimitry Andric PyErr_SetString(PyExc_TypeError, "not a file"); 521bdd1243dSDimitry Andric SWIG_fail; 522130d950cSDimitry Andric } 5230eae32dcSDimitry Andric auto sp = unwrapOrSetPythonException( 5240eae32dcSDimitry Andric py_file.ConvertToFileForcingUseOfScriptingIOMethods(/*borrowed=*/true)); 525130d950cSDimitry Andric if (!sp) 526bdd1243dSDimitry Andric SWIG_fail; 527130d950cSDimitry Andric $1 = sp; 528130d950cSDimitry Andric} 529130d950cSDimitry Andric 530130d950cSDimitry Andric%typecheck(SWIG_TYPECHECK_POINTER) lldb::FileSP { 531130d950cSDimitry Andric if (PythonFile::Check($input)) { 532130d950cSDimitry Andric $1 = 1; 533130d950cSDimitry Andric } else { 534130d950cSDimitry Andric PyErr_Clear(); 535130d950cSDimitry Andric $1 = 0; 536130d950cSDimitry Andric } 537130d950cSDimitry Andric} 538130d950cSDimitry Andric 539130d950cSDimitry Andric%typemap(out) lldb::FileSP { 540130d950cSDimitry Andric $result = nullptr; 541f3fd488fSDimitry Andric const lldb::FileSP &sp = $1; 542130d950cSDimitry Andric if (sp) { 543130d950cSDimitry Andric PythonFile pyfile = unwrapOrSetPythonException(PythonFile::FromFile(*sp)); 544130d950cSDimitry Andric if (!pyfile.IsValid()) 545bdd1243dSDimitry Andric SWIG_fail; 546130d950cSDimitry Andric $result = pyfile.release(); 547130d950cSDimitry Andric } 5480eae32dcSDimitry Andric if (!$result) { 549130d950cSDimitry Andric $result = Py_None; 550130d950cSDimitry Andric Py_INCREF(Py_None); 551130d950cSDimitry Andric } 552130d950cSDimitry Andric} 553130d950cSDimitry Andric 554130d950cSDimitry Andric%typemap(in) (const char* string, int len) { 5550eae32dcSDimitry Andric if ($input == Py_None) { 556130d950cSDimitry Andric $1 = NULL; 557130d950cSDimitry Andric $2 = 0; 5580eae32dcSDimitry Andric } else if (PythonString::Check($input)) { 559130d950cSDimitry Andric PythonString py_str(PyRefType::Borrowed, $input); 560130d950cSDimitry Andric llvm::StringRef str = py_str.GetString(); 561130d950cSDimitry Andric $1 = const_cast<char *>(str.data()); 562130d950cSDimitry Andric $2 = str.size(); 563130d950cSDimitry Andric // In Python 2, if $input is a PyUnicode object then this 564130d950cSDimitry Andric // will trigger a Unicode -> String conversion, in which 565130d950cSDimitry Andric // case the `PythonString` will now own the PyString. Thus 566130d950cSDimitry Andric // if it goes out of scope, the data will be deleted. The 567130d950cSDimitry Andric // only way to avoid this is to leak the Python object in 568130d950cSDimitry Andric // that case. Note that if there was no conversion, then 569130d950cSDimitry Andric // releasing the string will not leak anything, since we 570130d950cSDimitry Andric // created this as a borrowed reference. 571130d950cSDimitry Andric py_str.release(); 5720eae32dcSDimitry Andric } else { 573130d950cSDimitry Andric PyErr_SetString(PyExc_TypeError, "not a string-like object"); 574bdd1243dSDimitry Andric SWIG_fail; 575130d950cSDimitry Andric } 576130d950cSDimitry Andric} 577130d950cSDimitry Andric 578130d950cSDimitry Andric// These two pybuffer macros are copied out of swig/Lib/python/pybuffer.i, 579130d950cSDimitry Andric// and fixed so they will not crash if PyObject_GetBuffer fails. 580130d950cSDimitry Andric// https://github.com/swig/swig/issues/1640 5815ffd83dbSDimitry Andric// 5825ffd83dbSDimitry Andric// I've also moved the call to PyBuffer_Release to the end of the SWIG wrapper, 5835ffd83dbSDimitry Andric// doing it right away is not legal according to the python buffer protocol. 584130d950cSDimitry Andric 585130d950cSDimitry Andric%define %pybuffer_mutable_binary(TYPEMAP, SIZE) 5865ffd83dbSDimitry Andric%typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) { 5870eae32dcSDimitry Andric int res; 5880eae32dcSDimitry Andric Py_ssize_t size = 0; 5890eae32dcSDimitry Andric void *buf = 0; 5905ffd83dbSDimitry Andric res = PyObject_GetBuffer($input, &view.buffer, PyBUF_WRITABLE); 591130d950cSDimitry Andric if (res < 0) { 592130d950cSDimitry Andric PyErr_Clear(); 593130d950cSDimitry Andric %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum); 594130d950cSDimitry Andric } 5955ffd83dbSDimitry Andric size = view.buffer.len; 5965ffd83dbSDimitry Andric buf = view.buffer.buf; 597130d950cSDimitry Andric $1 = ($1_ltype)buf; 598130d950cSDimitry Andric $2 = ($2_ltype)(size / sizeof($*1_type)); 599130d950cSDimitry Andric} 600130d950cSDimitry Andric%enddef 601130d950cSDimitry Andric 602130d950cSDimitry Andric%define %pybuffer_binary(TYPEMAP, SIZE) 6035ffd83dbSDimitry Andric%typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) { 6040eae32dcSDimitry Andric int res; 6050eae32dcSDimitry Andric Py_ssize_t size = 0; 6060eae32dcSDimitry Andric const void *buf = 0; 6075ffd83dbSDimitry Andric res = PyObject_GetBuffer($input, &view.buffer, PyBUF_CONTIG_RO); 608130d950cSDimitry Andric if (res < 0) { 609130d950cSDimitry Andric PyErr_Clear(); 610130d950cSDimitry Andric %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum); 611130d950cSDimitry Andric } 6125ffd83dbSDimitry Andric size = view.buffer.len; 6135ffd83dbSDimitry Andric buf = view.buffer.buf; 614130d950cSDimitry Andric $1 = ($1_ltype)buf; 615130d950cSDimitry Andric $2 = ($2_ltype)(size / sizeof($*1_type)); 616130d950cSDimitry Andric} 617130d950cSDimitry Andric%enddef 618130d950cSDimitry Andric 619130d950cSDimitry Andric%pybuffer_binary(const uint8_t *buf, size_t num_bytes); 620130d950cSDimitry Andric%pybuffer_mutable_binary(uint8_t *buf, size_t num_bytes); 62106c3fb27SDimitry Andric 62206c3fb27SDimitry Andric%typemap(in) (const char **symbol_name, uint32_t num_names) { 62306c3fb27SDimitry Andric using namespace lldb_private; 62406c3fb27SDimitry Andric /* Check if is a list */ 62506c3fb27SDimitry Andric if (PythonList::Check($input)) { 62606c3fb27SDimitry Andric PythonList list(PyRefType::Borrowed, $input); 62706c3fb27SDimitry Andric $2 = list.GetSize(); 62806c3fb27SDimitry Andric int i = 0; 62906c3fb27SDimitry Andric $1 = (char**)malloc(($2+1)*sizeof(char*)); 63006c3fb27SDimitry Andric for (i = 0; i < $2; i++) { 63106c3fb27SDimitry Andric PythonString py_str = list.GetItemAtIndex(i).AsType<PythonString>(); 63206c3fb27SDimitry Andric if (!py_str.IsAllocated()) { 63306c3fb27SDimitry Andric PyErr_SetString(PyExc_TypeError,"list must contain strings and blubby"); 63406c3fb27SDimitry Andric free($1); 63506c3fb27SDimitry Andric return nullptr; 63606c3fb27SDimitry Andric } 63706c3fb27SDimitry Andric 63806c3fb27SDimitry Andric $1[i] = const_cast<char*>(py_str.GetString().data()); 63906c3fb27SDimitry Andric } 64006c3fb27SDimitry Andric $1[i] = 0; 64106c3fb27SDimitry Andric } else if ($input == Py_None) { 64206c3fb27SDimitry Andric $1 = NULL; 64306c3fb27SDimitry Andric } else { 64406c3fb27SDimitry Andric PyErr_SetString(PyExc_TypeError,"not a list"); 64506c3fb27SDimitry Andric return NULL; 64606c3fb27SDimitry Andric } 64706c3fb27SDimitry Andric} 64806c3fb27SDimitry Andric 64906c3fb27SDimitry Andric// For lldb::SBPlatformLocateModuleCallback 65006c3fb27SDimitry Andric%typemap(in) (lldb::SBPlatformLocateModuleCallback callback, 65106c3fb27SDimitry Andric void *callback_baton) { 65206c3fb27SDimitry Andric if (!($input == Py_None || 65306c3fb27SDimitry Andric PyCallable_Check(reinterpret_cast<PyObject *>($input)))) { 65406c3fb27SDimitry Andric PyErr_SetString(PyExc_TypeError, "Need a callable object or None!"); 65506c3fb27SDimitry Andric SWIG_fail; 65606c3fb27SDimitry Andric } 65706c3fb27SDimitry Andric 65806c3fb27SDimitry Andric if ($input == Py_None) { 65906c3fb27SDimitry Andric $1 = nullptr; 66006c3fb27SDimitry Andric $2 = nullptr; 66106c3fb27SDimitry Andric } else { 66206c3fb27SDimitry Andric PythonCallable callable = Retain<PythonCallable>($input); 66306c3fb27SDimitry Andric if (!callable.IsValid()) { 66406c3fb27SDimitry Andric PyErr_SetString(PyExc_TypeError, "Need a valid callable object"); 66506c3fb27SDimitry Andric SWIG_fail; 66606c3fb27SDimitry Andric } 66706c3fb27SDimitry Andric 66806c3fb27SDimitry Andric llvm::Expected<PythonCallable::ArgInfo> arg_info = callable.GetArgInfo(); 66906c3fb27SDimitry Andric if (!arg_info) { 67006c3fb27SDimitry Andric PyErr_SetString(PyExc_TypeError, 67106c3fb27SDimitry Andric ("Could not get arguments: " + 67206c3fb27SDimitry Andric llvm::toString(arg_info.takeError())).c_str()); 67306c3fb27SDimitry Andric SWIG_fail; 67406c3fb27SDimitry Andric } 67506c3fb27SDimitry Andric 67606c3fb27SDimitry Andric if (arg_info.get().max_positional_args != 3) { 67706c3fb27SDimitry Andric PyErr_SetString(PyExc_TypeError, "Expected 3 argument callable object"); 67806c3fb27SDimitry Andric SWIG_fail; 67906c3fb27SDimitry Andric } 68006c3fb27SDimitry Andric 68106c3fb27SDimitry Andric // NOTE: When this is called multiple times, this will leak the Python 68206c3fb27SDimitry Andric // callable object as other callbacks, because this does not call Py_DECREF 68306c3fb27SDimitry Andric // the object. But it should be almost zero impact since this method is 68406c3fb27SDimitry Andric // expected to be called only once. 68506c3fb27SDimitry Andric 68606c3fb27SDimitry Andric // Don't lose the callback reference 68706c3fb27SDimitry Andric Py_INCREF($input); 68806c3fb27SDimitry Andric 68906c3fb27SDimitry Andric $1 = LLDBSwigPythonCallLocateModuleCallback; 69006c3fb27SDimitry Andric $2 = $input; 69106c3fb27SDimitry Andric } 69206c3fb27SDimitry Andric} 69306c3fb27SDimitry Andric 69406c3fb27SDimitry Andric%typemap(typecheck) (lldb::SBPlatformLocateModuleCallback callback, 69506c3fb27SDimitry Andric void *callback_baton) { 69606c3fb27SDimitry Andric $1 = $input == Py_None; 69706c3fb27SDimitry Andric $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input)); 69806c3fb27SDimitry Andric} 699