xref: /llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp (revision 2c1f46dcc609a1bf61ab979eebdd72f81823ff74)
1 //===-- PythonDataObjects.cpp ------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifdef LLDB_DISABLE_PYTHON
11 
12 // Python is disabled in this build
13 
14 #else
15 
16 #include "lldb-python.h"
17 #include "PythonDataObjects.h"
18 #include "ScriptInterpreterPython.h"
19 
20 #include "lldb/Core/Stream.h"
21 #include "lldb/Host/File.h"
22 #include "lldb/Interpreter/ScriptInterpreter.h"
23 
24 #include <stdio.h>
25 
26 using namespace lldb_private;
27 using namespace lldb;
28 
29 void
30 StructuredPythonObject::Dump(Stream &s) const
31 {
32     s << "Python Obj: 0x" << GetValue();
33 }
34 
35 //----------------------------------------------------------------------
36 // PythonObject
37 //----------------------------------------------------------------------
38 
39 void
40 PythonObject::Dump (Stream &strm) const
41 {
42     if (m_py_obj)
43     {
44         FILE *file = ::tmpfile();
45         if (file)
46         {
47             ::PyObject_Print (m_py_obj, file, 0);
48             const long length = ftell (file);
49             if (length)
50             {
51                 ::rewind(file);
52                 std::vector<char> file_contents (length,'\0');
53                 const size_t length_read = ::fread (file_contents.data(), 1, file_contents.size(), file);
54                 if (length_read > 0)
55                     strm.Write (file_contents.data(), length_read);
56             }
57             ::fclose (file);
58         }
59     }
60     else
61         strm.PutCString ("NULL");
62 }
63 
64 PyObjectType
65 PythonObject::GetObjectType() const
66 {
67     if (IsNULLOrNone())
68         return PyObjectType::None;
69 
70     if (PyList_Check(m_py_obj))
71         return PyObjectType::List;
72     if (PyDict_Check(m_py_obj))
73         return PyObjectType::Dictionary;
74     if (PyString_Check(m_py_obj))
75         return PyObjectType::String;
76     if (PyInt_Check(m_py_obj) || PyLong_Check(m_py_obj))
77         return PyObjectType::Integer;
78     return PyObjectType::Unknown;
79 }
80 
81 PythonString
82 PythonObject::Repr ()
83 {
84     if (!m_py_obj)
85         return PythonString ();
86     PyObject *repr = PyObject_Repr(m_py_obj);
87     if (!repr)
88         return PythonString ();
89     return PythonString(repr);
90 }
91 
92 PythonString
93 PythonObject::Str ()
94 {
95     if (!m_py_obj)
96         return PythonString ();
97     PyObject *str = PyObject_Str(m_py_obj);
98     if (!str)
99         return PythonString ();
100     return PythonString(str);
101 }
102 
103 bool
104 PythonObject::IsNULLOrNone () const
105 {
106     return ((m_py_obj == nullptr) || (m_py_obj == Py_None));
107 }
108 
109 StructuredData::ObjectSP
110 PythonObject::CreateStructuredObject() const
111 {
112     switch (GetObjectType())
113     {
114         case PyObjectType::Dictionary:
115             return PythonDictionary(m_py_obj).CreateStructuredDictionary();
116         case PyObjectType::Integer:
117             return PythonInteger(m_py_obj).CreateStructuredInteger();
118         case PyObjectType::List:
119             return PythonList(m_py_obj).CreateStructuredArray();
120         case PyObjectType::String:
121             return PythonString(m_py_obj).CreateStructuredString();
122         case PyObjectType::None:
123             return StructuredData::ObjectSP();
124         default:
125             return StructuredData::ObjectSP(new StructuredPythonObject(m_py_obj));
126     }
127 }
128 
129 //----------------------------------------------------------------------
130 // PythonString
131 //----------------------------------------------------------------------
132 
133 PythonString::PythonString (PyObject *py_obj) :
134     PythonObject()
135 {
136     Reset(py_obj); // Use "Reset()" to ensure that py_obj is a string
137 }
138 
139 PythonString::PythonString (const PythonObject &object) :
140     PythonObject()
141 {
142     Reset(object.get()); // Use "Reset()" to ensure that py_obj is a string
143 }
144 
145 PythonString::PythonString (llvm::StringRef string) :
146     PythonObject(PyString_FromStringAndSize(string.data(), string.size()))
147 {
148 }
149 
150 PythonString::PythonString(const char *string) :
151     PythonObject(PyString_FromString(string))
152 {
153 }
154 
155 PythonString::PythonString () :
156     PythonObject()
157 {
158 }
159 
160 PythonString::~PythonString ()
161 {
162 }
163 
164 bool
165 PythonString::Reset (PyObject *py_obj)
166 {
167     if (py_obj && PyString_Check(py_obj))
168         return PythonObject::Reset(py_obj);
169 
170     PythonObject::Reset(nullptr);
171     return py_obj == nullptr;
172 }
173 
174 llvm::StringRef
175 PythonString::GetString() const
176 {
177     if (m_py_obj)
178         return llvm::StringRef(PyString_AsString(m_py_obj), GetSize());
179     return llvm::StringRef();
180 }
181 
182 size_t
183 PythonString::GetSize() const
184 {
185     if (m_py_obj)
186         return PyString_Size(m_py_obj);
187     return 0;
188 }
189 
190 void
191 PythonString::SetString (llvm::StringRef string)
192 {
193     PythonObject::Reset(PyString_FromStringAndSize(string.data(), string.size()));
194 }
195 
196 StructuredData::StringSP
197 PythonString::CreateStructuredString() const
198 {
199     StructuredData::StringSP result(new StructuredData::String);
200     result->SetValue(GetString());
201     return result;
202 }
203 
204 //----------------------------------------------------------------------
205 // PythonInteger
206 //----------------------------------------------------------------------
207 
208 PythonInteger::PythonInteger (PyObject *py_obj) :
209     PythonObject()
210 {
211     Reset(py_obj); // Use "Reset()" to ensure that py_obj is a integer type
212 }
213 
214 PythonInteger::PythonInteger (const PythonObject &object) :
215     PythonObject()
216 {
217     Reset(object.get()); // Use "Reset()" to ensure that py_obj is a integer type
218 }
219 
220 PythonInteger::PythonInteger (int64_t value) :
221     PythonObject()
222 {
223     SetInteger (value);
224 }
225 
226 
227 PythonInteger::~PythonInteger ()
228 {
229 }
230 
231 bool
232 PythonInteger::Reset (PyObject *py_obj)
233 {
234     if (py_obj)
235     {
236         if (PyInt_Check (py_obj) || PyLong_Check(py_obj))
237             return PythonObject::Reset(py_obj);
238     }
239 
240     PythonObject::Reset(nullptr);
241     return py_obj == nullptr;
242 }
243 
244 int64_t
245 PythonInteger::GetInteger() const
246 {
247     if (m_py_obj)
248     {
249         if (PyInt_Check(m_py_obj))
250             return PyInt_AsLong(m_py_obj);
251         else if (PyLong_Check(m_py_obj))
252             return PyLong_AsLongLong(m_py_obj);
253     }
254     return UINT64_MAX;
255 }
256 
257 void
258 PythonInteger::SetInteger (int64_t value)
259 {
260     PythonObject::Reset(PyLong_FromLongLong(value));
261 }
262 
263 StructuredData::IntegerSP
264 PythonInteger::CreateStructuredInteger() const
265 {
266     StructuredData::IntegerSP result(new StructuredData::Integer);
267     result->SetValue(GetInteger());
268     return result;
269 }
270 
271 //----------------------------------------------------------------------
272 // PythonList
273 //----------------------------------------------------------------------
274 
275 PythonList::PythonList (bool create_empty) :
276     PythonObject(create_empty ? PyList_New(0) : nullptr)
277 {
278 }
279 
280 PythonList::PythonList (uint32_t count) :
281     PythonObject(PyList_New(count))
282 {
283 }
284 
285 PythonList::PythonList (PyObject *py_obj) :
286     PythonObject()
287 {
288     Reset(py_obj); // Use "Reset()" to ensure that py_obj is a list
289 }
290 
291 
292 PythonList::PythonList (const PythonObject &object) :
293     PythonObject()
294 {
295     Reset(object.get()); // Use "Reset()" to ensure that py_obj is a list
296 }
297 
298 PythonList::~PythonList ()
299 {
300 }
301 
302 bool
303 PythonList::Reset (PyObject *py_obj)
304 {
305     if (py_obj && PyList_Check(py_obj))
306         return PythonObject::Reset(py_obj);
307 
308     PythonObject::Reset(nullptr);
309     return py_obj == nullptr;
310 }
311 
312 uint32_t
313 PythonList::GetSize() const
314 {
315     if (m_py_obj)
316         return PyList_GET_SIZE(m_py_obj);
317     return 0;
318 }
319 
320 PythonObject
321 PythonList::GetItemAtIndex(uint32_t index) const
322 {
323     if (m_py_obj)
324         return PythonObject(PyList_GetItem(m_py_obj, index));
325     return PythonObject();
326 }
327 
328 void
329 PythonList::SetItemAtIndex (uint32_t index, const PythonObject & object)
330 {
331     if (m_py_obj && object)
332         PyList_SetItem(m_py_obj, index, object.get());
333 }
334 
335 void
336 PythonList::AppendItem (const PythonObject &object)
337 {
338     if (m_py_obj && object)
339         PyList_Append(m_py_obj, object.get());
340 }
341 
342 StructuredData::ArraySP
343 PythonList::CreateStructuredArray() const
344 {
345     StructuredData::ArraySP result(new StructuredData::Array);
346     uint32_t count = GetSize();
347     for (uint32_t i = 0; i < count; ++i)
348     {
349         PythonObject obj = GetItemAtIndex(i);
350         result->AddItem(obj.CreateStructuredObject());
351     }
352     return result;
353 }
354 
355 //----------------------------------------------------------------------
356 // PythonDictionary
357 //----------------------------------------------------------------------
358 
359 PythonDictionary::PythonDictionary (bool create_empty) :
360 PythonObject(create_empty ? PyDict_New() : nullptr)
361 {
362 }
363 
364 PythonDictionary::PythonDictionary (PyObject *py_obj) :
365     PythonObject(py_obj)
366 {
367     Reset(py_obj); // Use "Reset()" to ensure that py_obj is a dictionary
368 }
369 
370 
371 PythonDictionary::PythonDictionary (const PythonObject &object) :
372     PythonObject()
373 {
374     Reset(object.get()); // Use "Reset()" to ensure that py_obj is a dictionary
375 }
376 
377 PythonDictionary::~PythonDictionary ()
378 {
379 }
380 
381 bool
382 PythonDictionary::Reset (PyObject *py_obj)
383 {
384     if (py_obj && PyDict_Check(py_obj))
385         return PythonObject::Reset(py_obj);
386 
387     PythonObject::Reset(nullptr);
388     return py_obj == nullptr;
389 }
390 
391 uint32_t
392 PythonDictionary::GetSize() const
393 {
394     if (m_py_obj)
395         return PyDict_Size(m_py_obj);
396     return 0;
397 }
398 
399 PythonObject
400 PythonDictionary::GetItemForKey (const char *key) const
401 {
402     if (key && key[0])
403     {
404         PythonString python_key(key);
405         return GetItemForKey(python_key);
406     }
407     return PythonObject();
408 }
409 
410 
411 PythonObject
412 PythonDictionary::GetItemForKey (const PythonString &key) const
413 {
414     if (m_py_obj && key)
415         return PythonObject(PyDict_GetItem(m_py_obj, key.get()));
416     return PythonObject();
417 }
418 
419 
420 const char *
421 PythonDictionary::GetItemForKeyAsString (const PythonString &key, const char *fail_value) const
422 {
423     if (m_py_obj && key)
424     {
425         PyObject *py_obj = PyDict_GetItem(m_py_obj, key.get());
426         if (py_obj && PyString_Check(py_obj))
427             return PyString_AsString(py_obj);
428     }
429     return fail_value;
430 }
431 
432 int64_t
433 PythonDictionary::GetItemForKeyAsInteger (const PythonString &key, int64_t fail_value) const
434 {
435     if (m_py_obj && key)
436     {
437         PyObject *py_obj = PyDict_GetItem(m_py_obj, key.get());
438         if (py_obj)
439         {
440             if (PyInt_Check(py_obj))
441                 return PyInt_AsLong(py_obj);
442 
443             if (PyLong_Check(py_obj))
444                 return PyLong_AsLong(py_obj);
445         }
446     }
447     return fail_value;
448 }
449 
450 PythonList
451 PythonDictionary::GetKeys () const
452 {
453     if (m_py_obj)
454         return PythonList(PyDict_Keys(m_py_obj));
455     return PythonList(true);
456 }
457 
458 PythonString
459 PythonDictionary::GetKeyAtPosition (uint32_t pos) const
460 {
461     PyObject *key, *value;
462     Py_ssize_t pos_iter = 0;
463 
464     if (m_py_obj)
465     {
466         while (PyDict_Next(m_py_obj, &pos_iter, &key, &value))
467         {
468             if (pos-- == 0)
469                 return PythonString(key);
470         }
471     }
472     return PythonString();
473 }
474 
475 PythonObject
476 PythonDictionary::GetValueAtPosition (uint32_t pos) const
477 {
478     PyObject *key, *value;
479     Py_ssize_t pos_iter = 0;
480 
481     if (!m_py_obj)
482         return PythonObject();
483 
484     while (PyDict_Next(m_py_obj, &pos_iter, &key, &value)) {
485         if (pos-- == 0)
486             return PythonObject(value);
487     }
488     return PythonObject();
489 }
490 
491 void
492 PythonDictionary::SetItemForKey (const PythonString &key, PyObject *value)
493 {
494     if (m_py_obj && key && value)
495         PyDict_SetItem(m_py_obj, key.get(), value);
496 }
497 
498 void
499 PythonDictionary::SetItemForKey (const PythonString &key, const PythonObject &value)
500 {
501     if (m_py_obj && key && value)
502         PyDict_SetItem(m_py_obj, key.get(), value.get());
503 }
504 
505 StructuredData::DictionarySP
506 PythonDictionary::CreateStructuredDictionary() const
507 {
508     StructuredData::DictionarySP result(new StructuredData::Dictionary);
509     PythonList keys(GetKeys());
510     uint32_t num_keys = keys.GetSize();
511     for (uint32_t i = 0; i < num_keys; ++i)
512     {
513         PythonObject key = keys.GetItemAtIndex(i);
514         PythonString key_str = key.Str();
515         PythonObject value = GetItemForKey(key);
516         StructuredData::ObjectSP structured_value = value.CreateStructuredObject();
517         result->AddItem(key_str.GetString(), structured_value);
518     }
519     return result;
520 }
521 
522 #endif
523