1/* Typemap definitions, to allow SWIG to properly handle 'char**' data types. */ 2 3%inline %{ 4 5#include "../bindings/python/python-typemaps.h" 6 7%} 8 9%typemap(in) char ** { 10 /* Check if is a list */ 11 if (PythonList::Check($input)) { 12 PythonList list(PyRefType::Borrowed, $input); 13 int size = list.GetSize(); 14 int i = 0; 15 $1 = (char **)malloc((size + 1) * sizeof(char *)); 16 for (i = 0; i < size; i++) { 17 PythonString py_str = list.GetItemAtIndex(i).AsType<PythonString>(); 18 if (!py_str.IsAllocated()) { 19 PyErr_SetString(PyExc_TypeError, "list must contain strings"); 20 free($1); 21 SWIG_fail; 22 } 23 24 $1[i] = const_cast<char *>(py_str.GetString().data()); 25 } 26 $1[i] = 0; 27 } else if ($input == Py_None) { 28 $1 = NULL; 29 } else { 30 PyErr_SetString(PyExc_TypeError, "not a list"); 31 SWIG_fail; 32 } 33} 34 35%typemap(typecheck) char ** { 36 /* Check if is a list */ 37 $1 = 1; 38 if (PythonList::Check($input)) { 39 PythonList list(PyRefType::Borrowed, $input); 40 int size = list.GetSize(); 41 int i = 0; 42 for (i = 0; i < size; i++) { 43 PythonString s = list.GetItemAtIndex(i).AsType<PythonString>(); 44 if (!s.IsAllocated()) { 45 $1 = 0; 46 } 47 } 48 } else { 49 $1 = (($input == Py_None) ? 1 : 0); 50 } 51} 52 53%typemap(freearg) char** { 54 free((char *) $1); 55} 56 57%typemap(out) char** { 58 int len; 59 int i; 60 len = 0; 61 while ($1[len]) 62 len++; 63 PythonList list(len); 64 for (i = 0; i < len; i++) 65 list.SetItemAtIndex(i, PythonString($1[i])); 66 $result = list.release(); 67} 68 69%typemap(in) lldb::tid_t { 70 PythonObject obj = Retain<PythonObject>($input); 71 lldb::tid_t value = unwrapOrSetPythonException(As<unsigned long long>(obj)); 72 if (PyErr_Occurred()) 73 SWIG_fail; 74 $1 = value; 75} 76 77%typemap(in) lldb::StateType { 78 PythonObject obj = Retain<PythonObject>($input); 79 unsigned long long state_type_value = 80 unwrapOrSetPythonException(As<unsigned long long>(obj)); 81 if (PyErr_Occurred()) 82 SWIG_fail; 83 if (state_type_value > lldb::StateType::kLastStateType) { 84 PyErr_SetString(PyExc_ValueError, "Not a valid StateType value"); 85 SWIG_fail; 86 } 87 $1 = static_cast<lldb::StateType>(state_type_value); 88} 89 90/* Typemap definitions to allow SWIG to properly handle char buffer. */ 91 92// typemap for a char buffer 93%typemap(in) (char *dst, size_t dst_len) { 94 if (!PyInt_Check($input)) { 95 PyErr_SetString(PyExc_ValueError, "Expecting an integer"); 96 SWIG_fail; 97 } 98 $2 = PyInt_AsLong($input); 99 if ($2 <= 0) { 100 PyErr_SetString(PyExc_ValueError, "Positive integer expected"); 101 SWIG_fail; 102 } 103 $1 = (char *)malloc($2); 104} 105// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated 106// as char data instead of byte data. 107%typemap(in) (void *char_buf, size_t size) = (char *dst, size_t dst_len); 108 109// Return the char buffer. Discarding any previous return result 110%typemap(argout) (char *dst, size_t dst_len) { 111 Py_XDECREF($result); /* Blow away any previous result */ 112 if (result == 0) { 113 PythonString string(""); 114 $result = string.release(); 115 Py_INCREF($result); 116 } else { 117 llvm::StringRef ref(static_cast<const char *>($1), result); 118 PythonString string(ref); 119 $result = string.release(); 120 } 121 free($1); 122} 123// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated 124// as char data instead of byte data. 125%typemap(argout) (void *char_buf, size_t size) = (char *dst, size_t dst_len); 126 127 128// typemap for handling an snprintf-like API like SBThread::GetStopDescription. 129%typemap(in) (char *dst_or_null, size_t dst_len) { 130 if (!PyInt_Check($input)) { 131 PyErr_SetString(PyExc_ValueError, "Expecting an integer"); 132 SWIG_fail; 133 } 134 $2 = PyInt_AsLong($input); 135 if ($2 <= 0) { 136 PyErr_SetString(PyExc_ValueError, "Positive integer expected"); 137 SWIG_fail; 138 } 139 $1 = (char *)malloc($2); 140} 141%typemap(argout) (char *dst_or_null, size_t dst_len) { 142 Py_XDECREF($result); /* Blow away any previous result */ 143 llvm::StringRef ref($1); 144 PythonString string(ref); 145 $result = string.release(); 146 free($1); 147} 148 149 150// typemap for an outgoing buffer 151// See also SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len). 152// Ditto for SBProcess::PutSTDIN(const char *src, size_t src_len). 153%typemap(in) (const char *cstr, uint32_t cstr_len), 154 (const char *src, size_t src_len) { 155 if (PythonString::Check($input)) { 156 PythonString str(PyRefType::Borrowed, $input); 157 $1 = (char *)str.GetString().data(); 158 $2 = str.GetSize(); 159 } else if (PythonByteArray::Check($input)) { 160 PythonByteArray bytearray(PyRefType::Borrowed, $input); 161 $1 = (char *)bytearray.GetBytes().data(); 162 $2 = bytearray.GetSize(); 163 } else if (PythonBytes::Check($input)) { 164 PythonBytes bytes(PyRefType::Borrowed, $input); 165 $1 = (char *)bytes.GetBytes().data(); 166 $2 = bytes.GetSize(); 167 } else { 168 PyErr_SetString(PyExc_ValueError, "Expecting a string"); 169 SWIG_fail; 170 } 171} 172// For SBProcess::WriteMemory, SBTarget::GetInstructions and SBDebugger::DispatchInput. 173%typemap(in) (const void *buf, size_t size), 174 (const void *data, size_t data_len) { 175 if (PythonString::Check($input)) { 176 PythonString str(PyRefType::Borrowed, $input); 177 $1 = (void *)str.GetString().data(); 178 $2 = str.GetSize(); 179 } else if (PythonByteArray::Check($input)) { 180 PythonByteArray bytearray(PyRefType::Borrowed, $input); 181 $1 = (void *)bytearray.GetBytes().data(); 182 $2 = bytearray.GetSize(); 183 } else if (PythonBytes::Check($input)) { 184 PythonBytes bytes(PyRefType::Borrowed, $input); 185 $1 = (void *)bytes.GetBytes().data(); 186 $2 = bytes.GetSize(); 187 } else { 188 PyErr_SetString(PyExc_ValueError, "Expecting a buffer"); 189 SWIG_fail; 190 } 191} 192 193// typemap for an incoming buffer 194// See also SBProcess::ReadMemory. 195%typemap(in) (void *buf, size_t size) { 196 if (PyInt_Check($input)) { 197 $2 = PyInt_AsLong($input); 198 } else if (PyLong_Check($input)) { 199 $2 = PyLong_AsLong($input); 200 } else { 201 PyErr_SetString(PyExc_ValueError, "Expecting an integer or long object"); 202 SWIG_fail; 203 } 204 if ($2 <= 0) { 205 PyErr_SetString(PyExc_ValueError, "Positive integer expected"); 206 SWIG_fail; 207 } 208 $1 = (void *)malloc($2); 209} 210 211// Return the buffer. Discarding any previous return result 212// See also SBProcess::ReadMemory. 213%typemap(argout) (void *buf, size_t size) { 214 Py_XDECREF($result); /* Blow away any previous result */ 215 if (result == 0) { 216 $result = Py_None; 217 Py_INCREF($result); 218 } else { 219 PythonBytes bytes(static_cast<const uint8_t *>($1), result); 220 $result = bytes.release(); 221 } 222 free($1); 223} 224 225%{ 226namespace { 227template <class T> 228T PyLongAsT(PyObject *obj) { 229 static_assert(true, "unsupported type"); 230} 231 232template <> uint64_t PyLongAsT<uint64_t>(PyObject *obj) { 233 return static_cast<uint64_t>(PyLong_AsUnsignedLongLong(obj)); 234} 235 236template <> uint32_t PyLongAsT<uint32_t>(PyObject *obj) { 237 return static_cast<uint32_t>(PyLong_AsUnsignedLong(obj)); 238} 239 240template <> int64_t PyLongAsT<int64_t>(PyObject *obj) { 241 return static_cast<int64_t>(PyLong_AsLongLong(obj)); 242} 243 244template <> int32_t PyLongAsT<int32_t>(PyObject *obj) { 245 return static_cast<int32_t>(PyLong_AsLong(obj)); 246} 247 248template <class T> bool SetNumberFromPyObject(T &number, PyObject *obj) { 249 if (PyInt_Check(obj)) 250 number = static_cast<T>(PyInt_AsLong(obj)); 251 else if (PyLong_Check(obj)) 252 number = PyLongAsT<T>(obj); 253 else 254 return false; 255 256 return true; 257} 258 259template <> bool SetNumberFromPyObject<double>(double &number, PyObject *obj) { 260 if (PyFloat_Check(obj)) { 261 number = PyFloat_AsDouble(obj); 262 return true; 263 } 264 265 return false; 266} 267 268} // namespace 269%} 270 271// these typemaps allow Python users to pass list objects 272// and have them turn into C++ arrays (this is useful, for instance 273// when creating SBData objects from lists of numbers) 274%typemap(in) (uint64_t* array, size_t array_len), 275 (uint32_t* array, size_t array_len), 276 (int64_t* array, size_t array_len), 277 (int32_t* array, size_t array_len), 278 (double* array, size_t array_len) { 279 /* Check if is a list */ 280 if (PyList_Check($input)) { 281 int size = PyList_Size($input); 282 int i = 0; 283 $2 = size; 284 $1 = ($1_type)malloc(size * sizeof($*1_type)); 285 for (i = 0; i < size; i++) { 286 PyObject *o = PyList_GetItem($input, i); 287 if (!SetNumberFromPyObject($1[i], o)) { 288 PyErr_SetString(PyExc_TypeError, "list must contain numbers"); 289 free($1); 290 SWIG_fail; 291 } 292 293 if (PyErr_Occurred()) { 294 free($1); 295 SWIG_fail; 296 } 297 } 298 } else if ($input == Py_None) { 299 $1 = NULL; 300 $2 = 0; 301 } else { 302 PyErr_SetString(PyExc_TypeError, "not a list"); 303 SWIG_fail; 304 } 305} 306 307%typemap(freearg) (uint64_t* array, size_t array_len), 308 (uint32_t* array, size_t array_len), 309 (int64_t* array, size_t array_len), 310 (int32_t* array, size_t array_len), 311 (double* array, size_t array_len) { 312 free($1); 313} 314 315// these typemaps wrap SBModule::GetVersion() from requiring a memory buffer 316// to the more Pythonic style where a list is returned and no previous allocation 317// is necessary - this will break if more than 50 versions are ever returned 318%typemap(typecheck) (uint32_t *versions, uint32_t num_versions) { 319 $1 = ($input == Py_None ? 1 : 0); 320} 321 322%typemap(in, numinputs=0) (uint32_t *versions) { 323 $1 = (uint32_t *)malloc(sizeof(uint32_t) * 50); 324} 325 326%typemap(in, numinputs=0) (uint32_t num_versions) { 327 $1 = 50; 328} 329 330%typemap(argout) (uint32_t *versions, uint32_t num_versions) { 331 uint32_t count = result; 332 if (count >= $2) 333 count = $2; 334 PyObject *list = PyList_New(count); 335 for (uint32_t j = 0; j < count; j++) { 336 PyObject *item = PyInt_FromLong($1[j]); 337 int ok = PyList_SetItem(list, j, item); 338 if (ok != 0) { 339 $result = Py_None; 340 break; 341 } 342 } 343 $result = list; 344} 345 346%typemap(freearg) (uint32_t *versions) { 347 free($1); 348} 349 350 351// For Log::LogOutputCallback 352%typemap(in) (lldb::LogOutputCallback log_callback, void *baton) { 353 if (!($input == Py_None || 354 PyCallable_Check(reinterpret_cast<PyObject *>($input)))) { 355 PyErr_SetString(PyExc_TypeError, "Need a callable object or None!"); 356 SWIG_fail; 357 } 358 359 // FIXME (filcab): We can't currently check if our callback is already 360 // LLDBSwigPythonCallPythonLogOutputCallback (to DECREF the previous 361 // baton) nor can we just remove all traces of a callback, if we want to 362 // revert to a file logging mechanism. 363 364 // Don't lose the callback reference 365 Py_INCREF($input); 366 $1 = LLDBSwigPythonCallPythonLogOutputCallback; 367 $2 = $input; 368} 369 370%typemap(typecheck) (lldb::LogOutputCallback log_callback, void *baton) { 371 $1 = $input == Py_None; 372 $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input)); 373} 374 375 376%typemap(in) lldb::FileSP { 377 PythonFile py_file(PyRefType::Borrowed, $input); 378 if (!py_file) { 379 PyErr_SetString(PyExc_TypeError, "not a file"); 380 SWIG_fail; 381 } 382 auto sp = unwrapOrSetPythonException(py_file.ConvertToFile()); 383 if (!sp) 384 SWIG_fail; 385 $1 = sp; 386} 387 388%typemap(in) lldb::FileSP FORCE_IO_METHODS { 389 PythonFile py_file(PyRefType::Borrowed, $input); 390 if (!py_file) { 391 PyErr_SetString(PyExc_TypeError, "not a file"); 392 SWIG_fail; 393 } 394 auto sp = unwrapOrSetPythonException( 395 py_file.ConvertToFileForcingUseOfScriptingIOMethods()); 396 if (!sp) 397 SWIG_fail; 398 $1 = sp; 399} 400 401%typemap(in) lldb::FileSP BORROWED { 402 PythonFile py_file(PyRefType::Borrowed, $input); 403 if (!py_file) { 404 PyErr_SetString(PyExc_TypeError, "not a file"); 405 SWIG_fail; 406 } 407 auto sp = 408 unwrapOrSetPythonException(py_file.ConvertToFile(/*borrowed=*/true)); 409 if (!sp) 410 SWIG_fail; 411 $1 = sp; 412} 413 414%typemap(in) lldb::FileSP BORROWED_FORCE_IO_METHODS { 415 PythonFile py_file(PyRefType::Borrowed, $input); 416 if (!py_file) { 417 PyErr_SetString(PyExc_TypeError, "not a file"); 418 SWIG_fail; 419 } 420 auto sp = unwrapOrSetPythonException( 421 py_file.ConvertToFileForcingUseOfScriptingIOMethods(/*borrowed=*/true)); 422 if (!sp) 423 SWIG_fail; 424 $1 = sp; 425} 426 427%typecheck(SWIG_TYPECHECK_POINTER) lldb::FileSP { 428 if (PythonFile::Check($input)) { 429 $1 = 1; 430 } else { 431 PyErr_Clear(); 432 $1 = 0; 433 } 434} 435 436%typemap(out) lldb::FileSP { 437 $result = nullptr; 438 const lldb::FileSP &sp = $1; 439 if (sp) { 440 PythonFile pyfile = unwrapOrSetPythonException(PythonFile::FromFile(*sp)); 441 if (!pyfile.IsValid()) 442 SWIG_fail; 443 $result = pyfile.release(); 444 } 445 if (!$result) { 446 $result = Py_None; 447 Py_INCREF(Py_None); 448 } 449} 450 451%typemap(in) (const char* string, int len) { 452 if ($input == Py_None) { 453 $1 = NULL; 454 $2 = 0; 455 } else if (PythonString::Check($input)) { 456 PythonString py_str(PyRefType::Borrowed, $input); 457 llvm::StringRef str = py_str.GetString(); 458 $1 = const_cast<char *>(str.data()); 459 $2 = str.size(); 460 // In Python 2, if $input is a PyUnicode object then this 461 // will trigger a Unicode -> String conversion, in which 462 // case the `PythonString` will now own the PyString. Thus 463 // if it goes out of scope, the data will be deleted. The 464 // only way to avoid this is to leak the Python object in 465 // that case. Note that if there was no conversion, then 466 // releasing the string will not leak anything, since we 467 // created this as a borrowed reference. 468 py_str.release(); 469 } else { 470 PyErr_SetString(PyExc_TypeError, "not a string-like object"); 471 SWIG_fail; 472 } 473} 474 475// These two pybuffer macros are copied out of swig/Lib/python/pybuffer.i, 476// and fixed so they will not crash if PyObject_GetBuffer fails. 477// https://github.com/swig/swig/issues/1640 478// 479// I've also moved the call to PyBuffer_Release to the end of the SWIG wrapper, 480// doing it right away is not legal according to the python buffer protocol. 481 482%define %pybuffer_mutable_binary(TYPEMAP, SIZE) 483%typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) { 484 int res; 485 Py_ssize_t size = 0; 486 void *buf = 0; 487 res = PyObject_GetBuffer($input, &view.buffer, PyBUF_WRITABLE); 488 if (res < 0) { 489 PyErr_Clear(); 490 %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum); 491 } 492 size = view.buffer.len; 493 buf = view.buffer.buf; 494 $1 = ($1_ltype)buf; 495 $2 = ($2_ltype)(size / sizeof($*1_type)); 496} 497%enddef 498 499%define %pybuffer_binary(TYPEMAP, SIZE) 500%typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) { 501 int res; 502 Py_ssize_t size = 0; 503 const void *buf = 0; 504 res = PyObject_GetBuffer($input, &view.buffer, PyBUF_CONTIG_RO); 505 if (res < 0) { 506 PyErr_Clear(); 507 %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum); 508 } 509 size = view.buffer.len; 510 buf = view.buffer.buf; 511 $1 = ($1_ltype)buf; 512 $2 = ($2_ltype)(size / sizeof($*1_type)); 513} 514%enddef 515 516%pybuffer_binary(const uint8_t *buf, size_t num_bytes); 517%pybuffer_mutable_binary(uint8_t *buf, size_t num_bytes); 518