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