Bug Summary

File:tools/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
Warning:line 389, column 7
Access to field 'ob_type' results in a dereference of a null pointer (loaded from variable 'py_obj')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name PythonDataObjects.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-8/lib/clang/8.0.0 -D HAVE_ROUND -D LLDB_CONFIGURATION_RELEASE -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/source/Plugins/ScriptInterpreter/Python -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/ScriptInterpreter/Python -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn345461/include -I /usr/include/python2.7 -I /build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/../clang/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/. -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/8.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-strict-aliasing -Wno-deprecated-register -Wno-vla-extension -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/source/Plugins/ScriptInterpreter/Python -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-10-27-211344-32123-1 -x c++ /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp -faddrsig

/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp

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 "PythonDataObjects.h"
17#include "ScriptInterpreterPython.h"
18
19#include "lldb/Host/File.h"
20#include "lldb/Host/FileSystem.h"
21#include "lldb/Interpreter/ScriptInterpreter.h"
22#include "lldb/Utility/Stream.h"
23
24#include "llvm/Support/ConvertUTF.h"
25
26#include <stdio.h>
27
28#include "llvm/ADT/StringSwitch.h"
29
30using namespace lldb_private;
31using namespace lldb;
32
33void StructuredPythonObject::Dump(Stream &s, bool pretty_print) const {
34 s << "Python Obj: 0x" << GetValue();
35}
36
37//----------------------------------------------------------------------
38// PythonObject
39//----------------------------------------------------------------------
40
41void PythonObject::Dump(Stream &strm) const {
42 if (m_py_obj) {
43 FILE *file = ::tmpfile();
44 if (file) {
45 ::PyObject_Print(m_py_obj, file, 0);
46 const long length = ftell(file);
47 if (length) {
48 ::rewind(file);
49 std::vector<char> file_contents(length, '\0');
50 const size_t length_read =
51 ::fread(file_contents.data(), 1, file_contents.size(), file);
52 if (length_read > 0)
53 strm.Write(file_contents.data(), length_read);
54 }
55 ::fclose(file);
56 }
57 } else
58 strm.PutCString("NULL");
59}
60
61PyObjectType PythonObject::GetObjectType() const {
62 if (!IsAllocated())
63 return PyObjectType::None;
64
65 if (PythonModule::Check(m_py_obj))
66 return PyObjectType::Module;
67 if (PythonList::Check(m_py_obj))
68 return PyObjectType::List;
69 if (PythonTuple::Check(m_py_obj))
70 return PyObjectType::Tuple;
71 if (PythonDictionary::Check(m_py_obj))
72 return PyObjectType::Dictionary;
73 if (PythonString::Check(m_py_obj))
74 return PyObjectType::String;
75#if PY_MAJOR_VERSION2 >= 3
76 if (PythonBytes::Check(m_py_obj))
77 return PyObjectType::Bytes;
78#endif
79 if (PythonByteArray::Check(m_py_obj))
80 return PyObjectType::ByteArray;
81 if (PythonInteger::Check(m_py_obj))
82 return PyObjectType::Integer;
83 if (PythonFile::Check(m_py_obj))
84 return PyObjectType::File;
85 if (PythonCallable::Check(m_py_obj))
86 return PyObjectType::Callable;
87 return PyObjectType::Unknown;
88}
89
90PythonString PythonObject::Repr() const {
91 if (!m_py_obj)
92 return PythonString();
93 PyObject *repr = PyObject_Repr(m_py_obj);
94 if (!repr)
95 return PythonString();
96 return PythonString(PyRefType::Owned, repr);
97}
98
99PythonString PythonObject::Str() const {
100 if (!m_py_obj)
101 return PythonString();
102 PyObject *str = PyObject_Str(m_py_obj);
103 if (!str)
104 return PythonString();
105 return PythonString(PyRefType::Owned, str);
106}
107
108PythonObject
109PythonObject::ResolveNameWithDictionary(llvm::StringRef name,
110 const PythonDictionary &dict) {
111 size_t dot_pos = name.find_first_of('.');
112 llvm::StringRef piece = name.substr(0, dot_pos);
113 PythonObject result = dict.GetItemForKey(PythonString(piece));
114 if (dot_pos == llvm::StringRef::npos) {
115 // There was no dot, we're done.
116 return result;
117 }
118
119 // There was a dot. The remaining portion of the name should be looked up in
120 // the context of the object that was found in the dictionary.
121 return result.ResolveName(name.substr(dot_pos + 1));
122}
123
124PythonObject PythonObject::ResolveName(llvm::StringRef name) const {
125 // Resolve the name in the context of the specified object. If, for example,
126 // `this` refers to a PyModule, then this will look for `name` in this
127 // module. If `this` refers to a PyType, then it will resolve `name` as an
128 // attribute of that type. If `this` refers to an instance of an object,
129 // then it will resolve `name` as the value of the specified field.
130 //
131 // This function handles dotted names so that, for example, if `m_py_obj`
132 // refers to the `sys` module, and `name` == "path.append", then it will find
133 // the function `sys.path.append`.
134
135 size_t dot_pos = name.find_first_of('.');
136 if (dot_pos == llvm::StringRef::npos) {
137 // No dots in the name, we should be able to find the value immediately as
138 // an attribute of `m_py_obj`.
139 return GetAttributeValue(name);
140 }
141
142 // Look up the first piece of the name, and resolve the rest as a child of
143 // that.
144 PythonObject parent = ResolveName(name.substr(0, dot_pos));
145 if (!parent.IsAllocated())
146 return PythonObject();
147
148 // Tail recursion.. should be optimized by the compiler
149 return parent.ResolveName(name.substr(dot_pos + 1));
150}
151
152bool PythonObject::HasAttribute(llvm::StringRef attr) const {
153 if (!IsValid())
154 return false;
155 PythonString py_attr(attr);
156 return !!PyObject_HasAttr(m_py_obj, py_attr.get());
157}
158
159PythonObject PythonObject::GetAttributeValue(llvm::StringRef attr) const {
160 if (!IsValid())
161 return PythonObject();
162
163 PythonString py_attr(attr);
164 if (!PyObject_HasAttr(m_py_obj, py_attr.get()))
165 return PythonObject();
166
167 return PythonObject(PyRefType::Owned,
168 PyObject_GetAttr(m_py_obj, py_attr.get()));
169}
170
171bool PythonObject::IsNone() const { return m_py_obj == Py_None(&_Py_NoneStruct); }
172
173bool PythonObject::IsValid() const { return m_py_obj != nullptr; }
174
175bool PythonObject::IsAllocated() const { return IsValid() && !IsNone(); }
176
177StructuredData::ObjectSP PythonObject::CreateStructuredObject() const {
178 switch (GetObjectType()) {
4
Control jumps to 'case Dictionary:' at line 179
14
Control jumps to 'case String:' at line 187
179 case PyObjectType::Dictionary:
180 return PythonDictionary(PyRefType::Borrowed, m_py_obj)
5
Calling 'PythonDictionary::CreateStructuredDictionary'
181 .CreateStructuredDictionary();
182 case PyObjectType::Integer:
183 return PythonInteger(PyRefType::Borrowed, m_py_obj)
184 .CreateStructuredInteger();
185 case PyObjectType::List:
186 return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray();
187 case PyObjectType::String:
188 return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
15
Passing null pointer value via 2nd parameter 'py_obj'
16
Calling constructor for 'PythonString'
189 case PyObjectType::Bytes:
190 return PythonBytes(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
191 case PyObjectType::ByteArray:
192 return PythonByteArray(PyRefType::Borrowed, m_py_obj)
193 .CreateStructuredString();
194 case PyObjectType::None:
195 return StructuredData::ObjectSP();
196 default:
197 return StructuredData::ObjectSP(new StructuredPythonObject(m_py_obj));
198 }
199}
200
201//----------------------------------------------------------------------
202// PythonString
203//----------------------------------------------------------------------
204PythonBytes::PythonBytes() : PythonObject() {}
205
206PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) : PythonObject() {
207 SetBytes(bytes);
208}
209
210PythonBytes::PythonBytes(const uint8_t *bytes, size_t length) : PythonObject() {
211 SetBytes(llvm::ArrayRef<uint8_t>(bytes, length));
212}
213
214PythonBytes::PythonBytes(PyRefType type, PyObject *py_obj) : PythonObject() {
215 Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string
216}
217
218PythonBytes::PythonBytes(const PythonBytes &object) : PythonObject(object) {}
219
220PythonBytes::~PythonBytes() {}
221
222bool PythonBytes::Check(PyObject *py_obj) {
223 if (!py_obj)
224 return false;
225 if (PyBytes_Check(py_obj)((((((PyObject*)(py_obj))->ob_type))->tp_flags & ((
1L<<27))) != 0)
)
226 return true;
227 return false;
228}
229
230void PythonBytes::Reset(PyRefType type, PyObject *py_obj) {
231 // Grab the desired reference type so that if we end up rejecting `py_obj` it
232 // still gets decremented if necessary.
233 PythonObject result(type, py_obj);
234
235 if (!PythonBytes::Check(py_obj)) {
236 PythonObject::Reset();
237 return;
238 }
239
240 // Calling PythonObject::Reset(const PythonObject&) will lead to stack
241 // overflow since it calls back into the virtual implementation.
242 PythonObject::Reset(PyRefType::Borrowed, result.get());
243}
244
245llvm::ArrayRef<uint8_t> PythonBytes::GetBytes() const {
246 if (!IsValid())
247 return llvm::ArrayRef<uint8_t>();
248
249 Py_ssize_t size;
250 char *c;
251
252 PyBytes_AsStringAndSizePyString_AsStringAndSize(m_py_obj, &c, &size);
253 return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
254}
255
256size_t PythonBytes::GetSize() const {
257 if (!IsValid())
258 return 0;
259 return PyBytes_SizePyString_Size(m_py_obj);
260}
261
262void PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes) {
263 const char *data = reinterpret_cast<const char *>(bytes.data());
264 PyObject *py_bytes = PyBytes_FromStringAndSizePyString_FromStringAndSize(data, bytes.size());
265 PythonObject::Reset(PyRefType::Owned, py_bytes);
266}
267
268StructuredData::StringSP PythonBytes::CreateStructuredString() const {
269 StructuredData::StringSP result(new StructuredData::String);
270 Py_ssize_t size;
271 char *c;
272 PyBytes_AsStringAndSizePyString_AsStringAndSize(m_py_obj, &c, &size);
273 result->SetValue(std::string(c, size));
274 return result;
275}
276
277PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes)
278 : PythonByteArray(bytes.data(), bytes.size()) {}
279
280PythonByteArray::PythonByteArray(const uint8_t *bytes, size_t length) {
281 const char *str = reinterpret_cast<const char *>(bytes);
282 Reset(PyRefType::Owned, PyByteArray_FromStringAndSize(str, length));
283}
284
285PythonByteArray::PythonByteArray(PyRefType type, PyObject *o) {
286 Reset(type, o);
287}
288
289PythonByteArray::PythonByteArray(const PythonBytes &object)
290 : PythonObject(object) {}
291
292PythonByteArray::~PythonByteArray() {}
293
294bool PythonByteArray::Check(PyObject *py_obj) {
295 if (!py_obj)
296 return false;
297 if (PyByteArray_Check(py_obj)((((PyObject*)(py_obj))->ob_type) == (&PyByteArray_Type
) || PyType_IsSubtype((((PyObject*)(py_obj))->ob_type), (&
PyByteArray_Type)))
)
298 return true;
299 return false;
300}
301
302void PythonByteArray::Reset(PyRefType type, PyObject *py_obj) {
303 // Grab the desired reference type so that if we end up rejecting `py_obj` it
304 // still gets decremented if necessary.
305 PythonObject result(type, py_obj);
306
307 if (!PythonByteArray::Check(py_obj)) {
308 PythonObject::Reset();
309 return;
310 }
311
312 // Calling PythonObject::Reset(const PythonObject&) will lead to stack
313 // overflow since it calls back into the virtual implementation.
314 PythonObject::Reset(PyRefType::Borrowed, result.get());
315}
316
317llvm::ArrayRef<uint8_t> PythonByteArray::GetBytes() const {
318 if (!IsValid())
319 return llvm::ArrayRef<uint8_t>();
320
321 char *c = PyByteArray_AsString(m_py_obj);
322 size_t size = GetSize();
323 return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
324}
325
326size_t PythonByteArray::GetSize() const {
327 if (!IsValid())
328 return 0;
329
330 return PyByteArray_Size(m_py_obj);
331}
332
333StructuredData::StringSP PythonByteArray::CreateStructuredString() const {
334 StructuredData::StringSP result(new StructuredData::String);
335 llvm::ArrayRef<uint8_t> bytes = GetBytes();
336 const char *str = reinterpret_cast<const char *>(bytes.data());
337 result->SetValue(std::string(str, bytes.size()));
338 return result;
339}
340
341//----------------------------------------------------------------------
342// PythonString
343//----------------------------------------------------------------------
344
345PythonString::PythonString(PyRefType type, PyObject *py_obj) : PythonObject() {
346 Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string
17
Passing null pointer value via 2nd parameter 'py_obj'
18
Calling 'PythonString::Reset'
347}
348
349PythonString::PythonString(const PythonString &object) : PythonObject(object) {}
350
351PythonString::PythonString(llvm::StringRef string) : PythonObject() {
352 SetString(string);
353}
354
355PythonString::PythonString(const char *string) : PythonObject() {
356 SetString(llvm::StringRef(string));
357}
358
359PythonString::PythonString() : PythonObject() {}
360
361PythonString::~PythonString() {}
362
363bool PythonString::Check(PyObject *py_obj) {
364 if (!py_obj)
365 return false;
366
367 if (PyUnicode_Check(py_obj)((((((PyObject*)(py_obj))->ob_type))->tp_flags & ((
1L<<28))) != 0)
)
368 return true;
369#if PY_MAJOR_VERSION2 < 3
370 if (PyString_Check(py_obj)((((((PyObject*)(py_obj))->ob_type))->tp_flags & ((
1L<<27))) != 0)
)
371 return true;
372#endif
373 return false;
374}
375
376void PythonString::Reset(PyRefType type, PyObject *py_obj) {
377 // Grab the desired reference type so that if we end up rejecting `py_obj` it
378 // still gets decremented if necessary.
379 PythonObject result(type, py_obj);
380
381 if (!PythonString::Check(py_obj)) {
19
Assuming the condition is false
20
Taking false branch
382 PythonObject::Reset();
383 return;
384 }
385#if PY_MAJOR_VERSION2 < 3
386 // In Python 2, Don't store PyUnicode objects directly, because we need
387 // access to their underlying character buffers which Python 2 doesn't
388 // provide.
389 if (PyUnicode_Check(py_obj)((((((PyObject*)(py_obj))->ob_type))->tp_flags & ((
1L<<28))) != 0)
)
21
Within the expansion of the macro 'PyUnicode_Check':
a
Access to field 'ob_type' results in a dereference of a null pointer (loaded from variable 'py_obj')
390 result.Reset(PyRefType::Owned, PyUnicode_AsUTF8StringPyUnicodeUCS4_AsUTF8String(result.get()));
391#endif
392 // Calling PythonObject::Reset(const PythonObject&) will lead to stack
393 // overflow since it calls back into the virtual implementation.
394 PythonObject::Reset(PyRefType::Borrowed, result.get());
395}
396
397llvm::StringRef PythonString::GetString() const {
398 if (!IsValid())
399 return llvm::StringRef();
400
401 Py_ssize_t size;
402 const char *data;
403
404#if PY_MAJOR_VERSION2 >= 3
405 data = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
406#else
407 char *c;
408 PyString_AsStringAndSize(m_py_obj, &c, &size);
409 data = c;
410#endif
411 return llvm::StringRef(data, size);
412}
413
414size_t PythonString::GetSize() const {
415 if (IsValid()) {
416#if PY_MAJOR_VERSION2 >= 3
417 return PyUnicode_GetSizePyUnicodeUCS4_GetSize(m_py_obj);
418#else
419 return PyString_Size(m_py_obj);
420#endif
421 }
422 return 0;
423}
424
425void PythonString::SetString(llvm::StringRef string) {
426#if PY_MAJOR_VERSION2 >= 3
427 PyObject *unicode = PyUnicode_FromStringAndSizePyUnicodeUCS4_FromStringAndSize(string.data(), string.size());
428 PythonObject::Reset(PyRefType::Owned, unicode);
429#else
430 PyObject *str = PyString_FromStringAndSize(string.data(), string.size());
431 PythonObject::Reset(PyRefType::Owned, str);
432#endif
433}
434
435StructuredData::StringSP PythonString::CreateStructuredString() const {
436 StructuredData::StringSP result(new StructuredData::String);
437 result->SetValue(GetString());
438 return result;
439}
440
441//----------------------------------------------------------------------
442// PythonInteger
443//----------------------------------------------------------------------
444
445PythonInteger::PythonInteger() : PythonObject() {}
446
447PythonInteger::PythonInteger(PyRefType type, PyObject *py_obj)
448 : PythonObject() {
449 Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a integer type
450}
451
452PythonInteger::PythonInteger(const PythonInteger &object)
453 : PythonObject(object) {}
454
455PythonInteger::PythonInteger(int64_t value) : PythonObject() {
456 SetInteger(value);
457}
458
459PythonInteger::~PythonInteger() {}
460
461bool PythonInteger::Check(PyObject *py_obj) {
462 if (!py_obj)
463 return false;
464
465#if PY_MAJOR_VERSION2 >= 3
466 // Python 3 does not have PyInt_Check. There is only one type of integral
467 // value, long.
468 return PyLong_Check(py_obj)((((((PyObject*)(py_obj))->ob_type))->tp_flags & ((
1L<<24))) != 0)
;
469#else
470 return PyLong_Check(py_obj)((((((PyObject*)(py_obj))->ob_type))->tp_flags & ((
1L<<24))) != 0)
|| PyInt_Check(py_obj)((((py_obj)->ob_type)->tp_flags & ((1L<<23)))
!= 0)
;
471#endif
472}
473
474void PythonInteger::Reset(PyRefType type, PyObject *py_obj) {
475 // Grab the desired reference type so that if we end up rejecting `py_obj` it
476 // still gets decremented if necessary.
477 PythonObject result(type, py_obj);
478
479 if (!PythonInteger::Check(py_obj)) {
480 PythonObject::Reset();
481 return;
482 }
483
484#if PY_MAJOR_VERSION2 < 3
485 // Always store this as a PyLong, which makes interoperability between Python
486 // 2.x and Python 3.x easier. This is only necessary in 2.x, since 3.x
487 // doesn't even have a PyInt.
488 if (PyInt_Check(py_obj)((((py_obj)->ob_type)->tp_flags & ((1L<<23)))
!= 0)
) {
489 // Since we converted the original object to a different type, the new
490 // object is an owned object regardless of the ownership semantics
491 // requested by the user.
492 result.Reset(PyRefType::Owned, PyLong_FromLongLong(PyInt_AsLong(py_obj)));
493 }
494#endif
495
496 assert(PyLong_Check(result.get()) &&((((((((PyObject*)(result.get()))->ob_type))->tp_flags &
((1L<<24))) != 0) && "Couldn't get a PyLong from this PyObject"
) ? static_cast<void> (0) : __assert_fail ("PyLong_Check(result.get()) && \"Couldn't get a PyLong from this PyObject\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp"
, 497, __PRETTY_FUNCTION__))
497 "Couldn't get a PyLong from this PyObject")((((((((PyObject*)(result.get()))->ob_type))->tp_flags &
((1L<<24))) != 0) && "Couldn't get a PyLong from this PyObject"
) ? static_cast<void> (0) : __assert_fail ("PyLong_Check(result.get()) && \"Couldn't get a PyLong from this PyObject\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp"
, 497, __PRETTY_FUNCTION__))
;
498
499 // Calling PythonObject::Reset(const PythonObject&) will lead to stack
500 // overflow since it calls back into the virtual implementation.
501 PythonObject::Reset(PyRefType::Borrowed, result.get());
502}
503
504int64_t PythonInteger::GetInteger() const {
505 if (m_py_obj) {
506 assert(PyLong_Check(m_py_obj) &&((((((((PyObject*)(m_py_obj))->ob_type))->tp_flags &
((1L<<24))) != 0) && "PythonInteger::GetInteger has a PyObject that isn't a PyLong"
) ? static_cast<void> (0) : __assert_fail ("PyLong_Check(m_py_obj) && \"PythonInteger::GetInteger has a PyObject that isn't a PyLong\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp"
, 507, __PRETTY_FUNCTION__))
507 "PythonInteger::GetInteger has a PyObject that isn't a PyLong")((((((((PyObject*)(m_py_obj))->ob_type))->tp_flags &
((1L<<24))) != 0) && "PythonInteger::GetInteger has a PyObject that isn't a PyLong"
) ? static_cast<void> (0) : __assert_fail ("PyLong_Check(m_py_obj) && \"PythonInteger::GetInteger has a PyObject that isn't a PyLong\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp"
, 507, __PRETTY_FUNCTION__))
;
508
509 int overflow = 0;
510 int64_t result = PyLong_AsLongLongAndOverflow(m_py_obj, &overflow);
511 if (overflow != 0) {
512 // We got an integer that overflows, like 18446744072853913392L we can't
513 // use PyLong_AsLongLong() as it will return 0xffffffffffffffff. If we
514 // use the unsigned long long it will work as expected.
515 const uint64_t uval = PyLong_AsUnsignedLongLong(m_py_obj);
516 result = static_cast<int64_t>(uval);
517 }
518 return result;
519 }
520 return UINT64_MAX(18446744073709551615UL);
521}
522
523void PythonInteger::SetInteger(int64_t value) {
524 PythonObject::Reset(PyRefType::Owned, PyLong_FromLongLong(value));
525}
526
527StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const {
528 StructuredData::IntegerSP result(new StructuredData::Integer);
529 result->SetValue(GetInteger());
530 return result;
531}
532
533//----------------------------------------------------------------------
534// PythonList
535//----------------------------------------------------------------------
536
537PythonList::PythonList(PyInitialValue value) : PythonObject() {
538 if (value == PyInitialValue::Empty)
539 Reset(PyRefType::Owned, PyList_New(0));
540}
541
542PythonList::PythonList(int list_size) : PythonObject() {
543 Reset(PyRefType::Owned, PyList_New(list_size));
544}
545
546PythonList::PythonList(PyRefType type, PyObject *py_obj) : PythonObject() {
547 Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a list
548}
549
550PythonList::PythonList(const PythonList &list) : PythonObject(list) {}
551
552PythonList::~PythonList() {}
553
554bool PythonList::Check(PyObject *py_obj) {
555 if (!py_obj)
556 return false;
557 return PyList_Check(py_obj)((((((PyObject*)(py_obj))->ob_type))->tp_flags & ((
1L<<25))) != 0)
;
558}
559
560void PythonList::Reset(PyRefType type, PyObject *py_obj) {
561 // Grab the desired reference type so that if we end up rejecting `py_obj` it
562 // still gets decremented if necessary.
563 PythonObject result(type, py_obj);
564
565 if (!PythonList::Check(py_obj)) {
566 PythonObject::Reset();
567 return;
568 }
569
570 // Calling PythonObject::Reset(const PythonObject&) will lead to stack
571 // overflow since it calls back into the virtual implementation.
572 PythonObject::Reset(PyRefType::Borrowed, result.get());
573}
574
575uint32_t PythonList::GetSize() const {
576 if (IsValid())
577 return PyList_GET_SIZE(m_py_obj)(((PyVarObject*)(m_py_obj))->ob_size);
578 return 0;
579}
580
581PythonObject PythonList::GetItemAtIndex(uint32_t index) const {
582 if (IsValid())
583 return PythonObject(PyRefType::Borrowed, PyList_GetItem(m_py_obj, index));
584 return PythonObject();
585}
586
587void PythonList::SetItemAtIndex(uint32_t index, const PythonObject &object) {
588 if (IsAllocated() && object.IsValid()) {
589 // PyList_SetItem is documented to "steal" a reference, so we need to
590 // convert it to an owned reference by incrementing it.
591 Py_INCREF(object.get())( ((PyObject*)(object.get()))->ob_refcnt++);
592 PyList_SetItem(m_py_obj, index, object.get());
593 }
594}
595
596void PythonList::AppendItem(const PythonObject &object) {
597 if (IsAllocated() && object.IsValid()) {
598 // `PyList_Append` does *not* steal a reference, so do not call `Py_INCREF`
599 // here like we do with `PyList_SetItem`.
600 PyList_Append(m_py_obj, object.get());
601 }
602}
603
604StructuredData::ArraySP PythonList::CreateStructuredArray() const {
605 StructuredData::ArraySP result(new StructuredData::Array);
606 uint32_t count = GetSize();
607 for (uint32_t i = 0; i < count; ++i) {
608 PythonObject obj = GetItemAtIndex(i);
609 result->AddItem(obj.CreateStructuredObject());
610 }
611 return result;
612}
613
614//----------------------------------------------------------------------
615// PythonTuple
616//----------------------------------------------------------------------
617
618PythonTuple::PythonTuple(PyInitialValue value) : PythonObject() {
619 if (value == PyInitialValue::Empty)
620 Reset(PyRefType::Owned, PyTuple_New(0));
621}
622
623PythonTuple::PythonTuple(int tuple_size) : PythonObject() {
624 Reset(PyRefType::Owned, PyTuple_New(tuple_size));
625}
626
627PythonTuple::PythonTuple(PyRefType type, PyObject *py_obj) : PythonObject() {
628 Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a tuple
629}
630
631PythonTuple::PythonTuple(const PythonTuple &tuple) : PythonObject(tuple) {}
632
633PythonTuple::PythonTuple(std::initializer_list<PythonObject> objects) {
634 m_py_obj = PyTuple_New(objects.size());
635
636 uint32_t idx = 0;
637 for (auto object : objects) {
638 if (object.IsValid())
639 SetItemAtIndex(idx, object);
640 idx++;
641 }
642}
643
644PythonTuple::PythonTuple(std::initializer_list<PyObject *> objects) {
645 m_py_obj = PyTuple_New(objects.size());
646
647 uint32_t idx = 0;
648 for (auto py_object : objects) {
649 PythonObject object(PyRefType::Borrowed, py_object);
650 if (object.IsValid())
651 SetItemAtIndex(idx, object);
652 idx++;
653 }
654}
655
656PythonTuple::~PythonTuple() {}
657
658bool PythonTuple::Check(PyObject *py_obj) {
659 if (!py_obj)
660 return false;
661 return PyTuple_Check(py_obj)((((((PyObject*)(py_obj))->ob_type))->tp_flags & ((
1L<<26))) != 0)
;
662}
663
664void PythonTuple::Reset(PyRefType type, PyObject *py_obj) {
665 // Grab the desired reference type so that if we end up rejecting `py_obj` it
666 // still gets decremented if necessary.
667 PythonObject result(type, py_obj);
668
669 if (!PythonTuple::Check(py_obj)) {
670 PythonObject::Reset();
671 return;
672 }
673
674 // Calling PythonObject::Reset(const PythonObject&) will lead to stack
675 // overflow since it calls back into the virtual implementation.
676 PythonObject::Reset(PyRefType::Borrowed, result.get());
677}
678
679uint32_t PythonTuple::GetSize() const {
680 if (IsValid())
681 return PyTuple_GET_SIZE(m_py_obj)(((PyVarObject*)(m_py_obj))->ob_size);
682 return 0;
683}
684
685PythonObject PythonTuple::GetItemAtIndex(uint32_t index) const {
686 if (IsValid())
687 return PythonObject(PyRefType::Borrowed, PyTuple_GetItem(m_py_obj, index));
688 return PythonObject();
689}
690
691void PythonTuple::SetItemAtIndex(uint32_t index, const PythonObject &object) {
692 if (IsAllocated() && object.IsValid()) {
693 // PyTuple_SetItem is documented to "steal" a reference, so we need to
694 // convert it to an owned reference by incrementing it.
695 Py_INCREF(object.get())( ((PyObject*)(object.get()))->ob_refcnt++);
696 PyTuple_SetItem(m_py_obj, index, object.get());
697 }
698}
699
700StructuredData::ArraySP PythonTuple::CreateStructuredArray() const {
701 StructuredData::ArraySP result(new StructuredData::Array);
702 uint32_t count = GetSize();
703 for (uint32_t i = 0; i < count; ++i) {
1
Assuming 'i' is < 'count'
2
Loop condition is true. Entering loop body
704 PythonObject obj = GetItemAtIndex(i);
705 result->AddItem(obj.CreateStructuredObject());
3
Calling 'PythonObject::CreateStructuredObject'
706 }
707 return result;
708}
709
710//----------------------------------------------------------------------
711// PythonDictionary
712//----------------------------------------------------------------------
713
714PythonDictionary::PythonDictionary(PyInitialValue value) : PythonObject() {
715 if (value == PyInitialValue::Empty)
716 Reset(PyRefType::Owned, PyDict_New());
717}
718
719PythonDictionary::PythonDictionary(PyRefType type, PyObject *py_obj)
720 : PythonObject() {
721 Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a dictionary
722}
723
724PythonDictionary::PythonDictionary(const PythonDictionary &object)
725 : PythonObject(object) {}
726
727PythonDictionary::~PythonDictionary() {}
728
729bool PythonDictionary::Check(PyObject *py_obj) {
730 if (!py_obj)
731 return false;
732
733 return PyDict_Check(py_obj)((((((PyObject*)(py_obj))->ob_type))->tp_flags & ((
1L<<29))) != 0)
;
734}
735
736void PythonDictionary::Reset(PyRefType type, PyObject *py_obj) {
737 // Grab the desired reference type so that if we end up rejecting `py_obj` it
738 // still gets decremented if necessary.
739 PythonObject result(type, py_obj);
740
741 if (!PythonDictionary::Check(py_obj)) {
742 PythonObject::Reset();
743 return;
744 }
745
746 // Calling PythonObject::Reset(const PythonObject&) will lead to stack
747 // overflow since it calls back into the virtual implementation.
748 PythonObject::Reset(PyRefType::Borrowed, result.get());
749}
750
751uint32_t PythonDictionary::GetSize() const {
752 if (IsValid())
753 return PyDict_Size(m_py_obj);
754 return 0;
755}
756
757PythonList PythonDictionary::GetKeys() const {
758 if (IsValid())
759 return PythonList(PyRefType::Owned, PyDict_Keys(m_py_obj));
760 return PythonList(PyInitialValue::Invalid);
761}
762
763PythonObject PythonDictionary::GetItemForKey(const PythonObject &key) const {
764 if (IsAllocated() && key.IsValid())
765 return PythonObject(PyRefType::Borrowed,
766 PyDict_GetItem(m_py_obj, key.get()));
767 return PythonObject();
9
Calling default constructor for 'PythonObject'
11
Returning from default constructor for 'PythonObject'
768}
769
770void PythonDictionary::SetItemForKey(const PythonObject &key,
771 const PythonObject &value) {
772 if (IsAllocated() && key.IsValid() && value.IsValid())
773 PyDict_SetItem(m_py_obj, key.get(), value.get());
774}
775
776StructuredData::DictionarySP
777PythonDictionary::CreateStructuredDictionary() const {
778 StructuredData::DictionarySP result(new StructuredData::Dictionary);
779 PythonList keys(GetKeys());
780 uint32_t num_keys = keys.GetSize();
781 for (uint32_t i = 0; i < num_keys; ++i) {
6
Assuming 'i' is < 'num_keys'
7
Loop condition is true. Entering loop body
782 PythonObject key = keys.GetItemAtIndex(i);
783 PythonObject value = GetItemForKey(key);
8
Calling 'PythonDictionary::GetItemForKey'
12
Returning from 'PythonDictionary::GetItemForKey'
784 StructuredData::ObjectSP structured_value = value.CreateStructuredObject();
13
Calling 'PythonObject::CreateStructuredObject'
785 result->AddItem(key.Str().GetString(), structured_value);
786 }
787 return result;
788}
789
790PythonModule::PythonModule() : PythonObject() {}
791
792PythonModule::PythonModule(PyRefType type, PyObject *py_obj) {
793 Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a module
794}
795
796PythonModule::PythonModule(const PythonModule &dict) : PythonObject(dict) {}
797
798PythonModule::~PythonModule() {}
799
800PythonModule PythonModule::BuiltinsModule() {
801#if PY_MAJOR_VERSION2 >= 3
802 return AddModule("builtins");
803#else
804 return AddModule("__builtin__");
805#endif
806}
807
808PythonModule PythonModule::MainModule() { return AddModule("__main__"); }
809
810PythonModule PythonModule::AddModule(llvm::StringRef module) {
811 std::string str = module.str();
812 return PythonModule(PyRefType::Borrowed, PyImport_AddModule(str.c_str()));
813}
814
815PythonModule PythonModule::ImportModule(llvm::StringRef module) {
816 std::string str = module.str();
817 return PythonModule(PyRefType::Owned, PyImport_ImportModule(str.c_str()));
818}
819
820bool PythonModule::Check(PyObject *py_obj) {
821 if (!py_obj)
822 return false;
823
824 return PyModule_Check(py_obj)((((PyObject*)(py_obj))->ob_type) == (&PyModule_Type) ||
PyType_IsSubtype((((PyObject*)(py_obj))->ob_type), (&
PyModule_Type)))
;
825}
826
827void PythonModule::Reset(PyRefType type, PyObject *py_obj) {
828 // Grab the desired reference type so that if we end up rejecting `py_obj` it
829 // still gets decremented if necessary.
830 PythonObject result(type, py_obj);
831
832 if (!PythonModule::Check(py_obj)) {
833 PythonObject::Reset();
834 return;
835 }
836
837 // Calling PythonObject::Reset(const PythonObject&) will lead to stack
838 // overflow since it calls back into the virtual implementation.
839 PythonObject::Reset(PyRefType::Borrowed, result.get());
840}
841
842PythonDictionary PythonModule::GetDictionary() const {
843 return PythonDictionary(PyRefType::Borrowed, PyModule_GetDict(m_py_obj));
844}
845
846PythonCallable::PythonCallable() : PythonObject() {}
847
848PythonCallable::PythonCallable(PyRefType type, PyObject *py_obj) {
849 Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a callable
850}
851
852PythonCallable::PythonCallable(const PythonCallable &callable)
853 : PythonObject(callable) {}
854
855PythonCallable::~PythonCallable() {}
856
857bool PythonCallable::Check(PyObject *py_obj) {
858 if (!py_obj)
859 return false;
860
861 return PyCallable_Check(py_obj);
862}
863
864void PythonCallable::Reset(PyRefType type, PyObject *py_obj) {
865 // Grab the desired reference type so that if we end up rejecting `py_obj` it
866 // still gets decremented if necessary.
867 PythonObject result(type, py_obj);
868
869 if (!PythonCallable::Check(py_obj)) {
870 PythonObject::Reset();
871 return;
872 }
873
874 // Calling PythonObject::Reset(const PythonObject&) will lead to stack
875 // overflow since it calls back into the virtual implementation.
876 PythonObject::Reset(PyRefType::Borrowed, result.get());
877}
878
879PythonCallable::ArgInfo PythonCallable::GetNumArguments() const {
880 ArgInfo result = {0, false, false, false};
881 if (!IsValid())
882 return result;
883
884 PyObject *py_func_obj = m_py_obj;
885 if (PyMethod_Check(py_func_obj)((py_func_obj)->ob_type == &PyMethod_Type)) {
886 py_func_obj = PyMethod_GET_FUNCTION(py_func_obj)(((PyMethodObject *)py_func_obj) -> im_func);
887 PythonObject im_self = GetAttributeValue("im_self");
888 if (im_self.IsValid() && !im_self.IsNone())
889 result.is_bound_method = true;
890 } else {
891 // see if this is a callable object with an __call__ method
892 if (!PyFunction_Check(py_func_obj)((((PyObject*)(py_func_obj))->ob_type) == &PyFunction_Type
)
) {
893 PythonObject __call__ = GetAttributeValue("__call__");
894 if (__call__.IsValid()) {
895 auto __callable__ = __call__.AsType<PythonCallable>();
896 if (__callable__.IsValid()) {
897 py_func_obj = PyMethod_GET_FUNCTION(__callable__.get())(((PyMethodObject *)__callable__.get()) -> im_func);
898 PythonObject im_self = GetAttributeValue("im_self");
899 if (im_self.IsValid() && !im_self.IsNone())
900 result.is_bound_method = true;
901 }
902 }
903 }
904 }
905
906 if (!py_func_obj)
907 return result;
908
909 PyCodeObject *code = (PyCodeObject *)PyFunction_GET_CODE(py_func_obj)(((PyFunctionObject *)py_func_obj) -> func_code);
910 if (!code)
911 return result;
912
913 result.count = code->co_argcount;
914 result.has_varargs = !!(code->co_flags & CO_VARARGS0x0004);
915 result.has_kwargs = !!(code->co_flags & CO_VARKEYWORDS0x0008);
916 return result;
917}
918
919PythonObject PythonCallable::operator()() {
920 return PythonObject(PyRefType::Owned, PyObject_CallObject(m_py_obj, nullptr));
921}
922
923PythonObject PythonCallable::
924operator()(std::initializer_list<PyObject *> args) {
925 PythonTuple arg_tuple(args);
926 return PythonObject(PyRefType::Owned,
927 PyObject_CallObject(m_py_obj, arg_tuple.get()));
928}
929
930PythonObject PythonCallable::
931operator()(std::initializer_list<PythonObject> args) {
932 PythonTuple arg_tuple(args);
933 return PythonObject(PyRefType::Owned,
934 PyObject_CallObject(m_py_obj, arg_tuple.get()));
935}
936
937PythonFile::PythonFile() : PythonObject() {}
938
939PythonFile::PythonFile(File &file, const char *mode) { Reset(file, mode); }
940
941PythonFile::PythonFile(const char *path, const char *mode) {
942 lldb_private::File file(path, GetOptionsFromMode(mode));
943 Reset(file, mode);
944}
945
946PythonFile::PythonFile(PyRefType type, PyObject *o) { Reset(type, o); }
947
948PythonFile::~PythonFile() {}
949
950bool PythonFile::Check(PyObject *py_obj) {
951#if PY_MAJOR_VERSION2 < 3
952 return PyFile_Check(py_obj)((((PyObject*)(py_obj))->ob_type) == (&PyFile_Type) ||
PyType_IsSubtype((((PyObject*)(py_obj))->ob_type), (&
PyFile_Type)))
;
953#else
954 // In Python 3, there is no `PyFile_Check`, and in fact PyFile is not even a
955 // first-class object type anymore. `PyFile_FromFd` is just a thin wrapper
956 // over `io.open()`, which returns some object derived from `io.IOBase`. As a
957 // result, the only way to detect a file in Python 3 is to check whether it
958 // inherits from `io.IOBase`. Since it is possible for non-files to also
959 // inherit from `io.IOBase`, we additionally verify that it has the `fileno`
960 // attribute, which should guarantee that it is backed by the file system.
961 PythonObject io_module(PyRefType::Owned, PyImport_ImportModule("io"));
962 PythonDictionary io_dict(PyRefType::Borrowed,
963 PyModule_GetDict(io_module.get()));
964 PythonObject io_base_class = io_dict.GetItemForKey(PythonString("IOBase"));
965
966 PythonObject object_type(PyRefType::Owned, PyObject_Type(py_obj));
967
968 if (1 != PyObject_IsSubclass(object_type.get(), io_base_class.get()))
969 return false;
970 if (!object_type.HasAttribute("fileno"))
971 return false;
972
973 return true;
974#endif
975}
976
977void PythonFile::Reset(PyRefType type, PyObject *py_obj) {
978 // Grab the desired reference type so that if we end up rejecting `py_obj` it
979 // still gets decremented if necessary.
980 PythonObject result(type, py_obj);
981
982 if (!PythonFile::Check(py_obj)) {
983 PythonObject::Reset();
984 return;
985 }
986
987 // Calling PythonObject::Reset(const PythonObject&) will lead to stack
988 // overflow since it calls back into the virtual implementation.
989 PythonObject::Reset(PyRefType::Borrowed, result.get());
990}
991
992void PythonFile::Reset(File &file, const char *mode) {
993 if (!file.IsValid()) {
994 Reset();
995 return;
996 }
997
998 char *cmode = const_cast<char *>(mode);
999#if PY_MAJOR_VERSION2 >= 3
1000 Reset(PyRefType::Owned, PyFile_FromFd(file.GetDescriptor(), nullptr, cmode,
1001 -1, nullptr, "ignore", nullptr, 0));
1002#else
1003 // Read through the Python source, doesn't seem to modify these strings
1004 Reset(PyRefType::Owned,
1005 PyFile_FromFile(file.GetStream(), const_cast<char *>(""), cmode,
1006 nullptr));
1007#endif
1008}
1009
1010uint32_t PythonFile::GetOptionsFromMode(llvm::StringRef mode) {
1011 if (mode.empty())
1012 return 0;
1013
1014 return llvm::StringSwitch<uint32_t>(mode.str())
1015 .Case("r", File::eOpenOptionRead)
1016 .Case("w", File::eOpenOptionWrite)
1017 .Case("a", File::eOpenOptionWrite | File::eOpenOptionAppend |
1018 File::eOpenOptionCanCreate)
1019 .Case("r+", File::eOpenOptionRead | File::eOpenOptionWrite)
1020 .Case("w+", File::eOpenOptionRead | File::eOpenOptionWrite |
1021 File::eOpenOptionCanCreate | File::eOpenOptionTruncate)
1022 .Case("a+", File::eOpenOptionRead | File::eOpenOptionWrite |
1023 File::eOpenOptionAppend | File::eOpenOptionCanCreate)
1024 .Default(0);
1025}
1026
1027bool PythonFile::GetUnderlyingFile(File &file) const {
1028 if (!IsValid())
1029 return false;
1030
1031 file.Close();
1032 // We don't own the file descriptor returned by this function, make sure the
1033 // File object knows about that.
1034 file.SetDescriptor(PyObject_AsFileDescriptor(m_py_obj), false);
1035 PythonString py_mode = GetAttributeValue("mode").AsType<PythonString>();
1036 file.SetOptions(PythonFile::GetOptionsFromMode(py_mode.GetString()));
1037 return file.IsValid();
1038}
1039
1040#endif

/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h

1//===-- PythonDataObjects.h--------------------------------------*- 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#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
11#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
12
13#ifndef LLDB_DISABLE_PYTHON
14
15// LLDB Python header must be included first
16#include "lldb-python.h"
17
18// C Includes
19// C++ Includes
20// Other libraries and framework includes
21// Project includes
22#include "lldb/Utility/Flags.h"
23
24#include "lldb/Host/File.h"
25#include "lldb/Interpreter/OptionValue.h"
26#include "lldb/Utility/ConstString.h"
27#include "lldb/Utility/StructuredData.h"
28#include "lldb/lldb-defines.h"
29
30#include "llvm/ADT/ArrayRef.h"
31
32namespace lldb_private {
33
34class PythonBytes;
35class PythonString;
36class PythonList;
37class PythonDictionary;
38class PythonInteger;
39
40class StructuredPythonObject : public StructuredData::Generic {
41public:
42 StructuredPythonObject() : StructuredData::Generic() {}
43
44 StructuredPythonObject(void *obj) : StructuredData::Generic(obj) {
45 Py_XINCREF(GetValue())do { if ((GetValue()) == __null) ; else ( ((PyObject*)(GetValue
()))->ob_refcnt++); } while (0)
;
46 }
47
48 ~StructuredPythonObject() override {
49 if (Py_IsInitialized())
50 Py_XDECREF(GetValue())do { if ((GetValue()) == __null) ; else do { if ( --((PyObject
*)(GetValue()))->ob_refcnt != 0) ; else ( (*(((PyObject*)(
(PyObject *)(GetValue())))->ob_type)->tp_dealloc)((PyObject
*)((PyObject *)(GetValue())))); } while (0); } while (0)
;
51 SetValue(nullptr);
52 }
53
54 bool IsValid() const override { return GetValue() && GetValue() != Py_None(&_Py_NoneStruct); }
55
56 void Dump(Stream &s, bool pretty_print = true) const override;
57
58private:
59 DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject)StructuredPythonObject(const StructuredPythonObject &) = delete
; const StructuredPythonObject &operator=(const StructuredPythonObject
&) = delete
;
60};
61
62enum class PyObjectType {
63 Unknown,
64 None,
65 Integer,
66 Dictionary,
67 List,
68 String,
69 Bytes,
70 ByteArray,
71 Module,
72 Callable,
73 Tuple,
74 File
75};
76
77enum class PyRefType {
78 Borrowed, // We are not given ownership of the incoming PyObject.
79 // We cannot safely hold it without calling Py_INCREF.
80 Owned // We have ownership of the incoming PyObject. We should
81 // not call Py_INCREF.
82};
83
84enum class PyInitialValue { Invalid, Empty };
85
86class PythonObject {
87public:
88 PythonObject() : m_py_obj(nullptr) {}
10
Null pointer value stored to 'value.m_py_obj'
89
90 PythonObject(PyRefType type, PyObject *py_obj) : m_py_obj(nullptr) {
91 Reset(type, py_obj);
92 }
93
94 PythonObject(const PythonObject &rhs) : m_py_obj(nullptr) { Reset(rhs); }
95
96 virtual ~PythonObject() { Reset(); }
97
98 void Reset() {
99 // Avoid calling the virtual method since it's not necessary
100 // to actually validate the type of the PyObject if we're
101 // just setting to null.
102 if (Py_IsInitialized())
103 Py_XDECREF(m_py_obj)do { if ((m_py_obj) == __null) ; else do { if ( --((PyObject*
)(m_py_obj))->ob_refcnt != 0) ; else ( (*(((PyObject*)((PyObject
*)(m_py_obj)))->ob_type)->tp_dealloc)((PyObject *)((PyObject
*)(m_py_obj)))); } while (0); } while (0)
;
104 m_py_obj = nullptr;
105 }
106
107 void Reset(const PythonObject &rhs) {
108 // Avoid calling the virtual method if it's not necessary
109 // to actually validate the type of the PyObject.
110 if (!rhs.IsValid())
111 Reset();
112 else
113 Reset(PyRefType::Borrowed, rhs.m_py_obj);
114 }
115
116 // PythonObject is implicitly convertible to PyObject *, which will call the
117 // wrong overload. We want to explicitly disallow this, since a PyObject
118 // *always* owns its reference. Therefore the overload which takes a
119 // PyRefType doesn't make sense, and the copy constructor should be used.
120 void Reset(PyRefType type, const PythonObject &ref) = delete;
121
122 virtual void Reset(PyRefType type, PyObject *py_obj) {
123 if (py_obj == m_py_obj)
124 return;
125
126 if (Py_IsInitialized())
127 Py_XDECREF(m_py_obj)do { if ((m_py_obj) == __null) ; else do { if ( --((PyObject*
)(m_py_obj))->ob_refcnt != 0) ; else ( (*(((PyObject*)((PyObject
*)(m_py_obj)))->ob_type)->tp_dealloc)((PyObject *)((PyObject
*)(m_py_obj)))); } while (0); } while (0)
;
128
129 m_py_obj = py_obj;
130
131 // If this is a borrowed reference, we need to convert it to
132 // an owned reference by incrementing it. If it is an owned
133 // reference (for example the caller allocated it with PyDict_New()
134 // then we must *not* increment it.
135 if (Py_IsInitialized() && type == PyRefType::Borrowed)
136 Py_XINCREF(m_py_obj)do { if ((m_py_obj) == __null) ; else ( ((PyObject*)(m_py_obj
))->ob_refcnt++); } while (0)
;
137 }
138
139 void Dump() const {
140 if (m_py_obj)
141 _PyObject_Dump(m_py_obj);
142 else
143 puts("NULL");
144 }
145
146 void Dump(Stream &strm) const;
147
148 PyObject *get() const { return m_py_obj; }
149
150 PyObject *release() {
151 PyObject *result = m_py_obj;
152 m_py_obj = nullptr;
153 return result;
154 }
155
156 PythonObject &operator=(const PythonObject &other) {
157 Reset(PyRefType::Borrowed, other.get());
158 return *this;
159 }
160
161 PyObjectType GetObjectType() const;
162
163 PythonString Repr() const;
164
165 PythonString Str() const;
166
167 static PythonObject ResolveNameWithDictionary(llvm::StringRef name,
168 const PythonDictionary &dict);
169
170 template <typename T>
171 static T ResolveNameWithDictionary(llvm::StringRef name,
172 const PythonDictionary &dict) {
173 return ResolveNameWithDictionary(name, dict).AsType<T>();
174 }
175
176 PythonObject ResolveName(llvm::StringRef name) const;
177
178 template <typename T> T ResolveName(llvm::StringRef name) const {
179 return ResolveName(name).AsType<T>();
180 }
181
182 bool HasAttribute(llvm::StringRef attribute) const;
183
184 PythonObject GetAttributeValue(llvm::StringRef attribute) const;
185
186 bool IsValid() const;
187
188 bool IsAllocated() const;
189
190 bool IsNone() const;
191
192 template <typename T> T AsType() const {
193 if (!T::Check(m_py_obj))
194 return T();
195 return T(PyRefType::Borrowed, m_py_obj);
196 }
197
198 StructuredData::ObjectSP CreateStructuredObject() const;
199
200protected:
201 PyObject *m_py_obj;
202};
203
204class PythonBytes : public PythonObject {
205public:
206 PythonBytes();
207 explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes);
208 PythonBytes(const uint8_t *bytes, size_t length);
209 PythonBytes(PyRefType type, PyObject *o);
210 PythonBytes(const PythonBytes &object);
211
212 ~PythonBytes() override;
213
214 static bool Check(PyObject *py_obj);
215
216 // Bring in the no-argument base class version
217 using PythonObject::Reset;
218
219 void Reset(PyRefType type, PyObject *py_obj) override;
220
221 llvm::ArrayRef<uint8_t> GetBytes() const;
222
223 size_t GetSize() const;
224
225 void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
226
227 StructuredData::StringSP CreateStructuredString() const;
228};
229
230class PythonByteArray : public PythonObject {
231public:
232 PythonByteArray();
233 explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes);
234 PythonByteArray(const uint8_t *bytes, size_t length);
235 PythonByteArray(PyRefType type, PyObject *o);
236 PythonByteArray(const PythonBytes &object);
237
238 ~PythonByteArray() override;
239
240 static bool Check(PyObject *py_obj);
241
242 // Bring in the no-argument base class version
243 using PythonObject::Reset;
244
245 void Reset(PyRefType type, PyObject *py_obj) override;
246
247 llvm::ArrayRef<uint8_t> GetBytes() const;
248
249 size_t GetSize() const;
250
251 void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
252
253 StructuredData::StringSP CreateStructuredString() const;
254};
255
256class PythonString : public PythonObject {
257public:
258 PythonString();
259 explicit PythonString(llvm::StringRef string);
260 explicit PythonString(const char *string);
261 PythonString(PyRefType type, PyObject *o);
262 PythonString(const PythonString &object);
263
264 ~PythonString() override;
265
266 static bool Check(PyObject *py_obj);
267
268 // Bring in the no-argument base class version
269 using PythonObject::Reset;
270
271 void Reset(PyRefType type, PyObject *py_obj) override;
272
273 llvm::StringRef GetString() const;
274
275 size_t GetSize() const;
276
277 void SetString(llvm::StringRef string);
278
279 StructuredData::StringSP CreateStructuredString() const;
280};
281
282class PythonInteger : public PythonObject {
283public:
284 PythonInteger();
285 explicit PythonInteger(int64_t value);
286 PythonInteger(PyRefType type, PyObject *o);
287 PythonInteger(const PythonInteger &object);
288
289 ~PythonInteger() override;
290
291 static bool Check(PyObject *py_obj);
292
293 // Bring in the no-argument base class version
294 using PythonObject::Reset;
295
296 void Reset(PyRefType type, PyObject *py_obj) override;
297
298 int64_t GetInteger() const;
299
300 void SetInteger(int64_t value);
301
302 StructuredData::IntegerSP CreateStructuredInteger() const;
303};
304
305class PythonList : public PythonObject {
306public:
307 PythonList() {}
308 explicit PythonList(PyInitialValue value);
309 explicit PythonList(int list_size);
310 PythonList(PyRefType type, PyObject *o);
311 PythonList(const PythonList &list);
312
313 ~PythonList() override;
314
315 static bool Check(PyObject *py_obj);
316
317 // Bring in the no-argument base class version
318 using PythonObject::Reset;
319
320 void Reset(PyRefType type, PyObject *py_obj) override;
321
322 uint32_t GetSize() const;
323
324 PythonObject GetItemAtIndex(uint32_t index) const;
325
326 void SetItemAtIndex(uint32_t index, const PythonObject &object);
327
328 void AppendItem(const PythonObject &object);
329
330 StructuredData::ArraySP CreateStructuredArray() const;
331};
332
333class PythonTuple : public PythonObject {
334public:
335 PythonTuple() {}
336 explicit PythonTuple(PyInitialValue value);
337 explicit PythonTuple(int tuple_size);
338 PythonTuple(PyRefType type, PyObject *o);
339 PythonTuple(const PythonTuple &tuple);
340 PythonTuple(std::initializer_list<PythonObject> objects);
341 PythonTuple(std::initializer_list<PyObject *> objects);
342
343 ~PythonTuple() override;
344
345 static bool Check(PyObject *py_obj);
346
347 // Bring in the no-argument base class version
348 using PythonObject::Reset;
349
350 void Reset(PyRefType type, PyObject *py_obj) override;
351
352 uint32_t GetSize() const;
353
354 PythonObject GetItemAtIndex(uint32_t index) const;
355
356 void SetItemAtIndex(uint32_t index, const PythonObject &object);
357
358 StructuredData::ArraySP CreateStructuredArray() const;
359};
360
361class PythonDictionary : public PythonObject {
362public:
363 PythonDictionary() {}
364 explicit PythonDictionary(PyInitialValue value);
365 PythonDictionary(PyRefType type, PyObject *o);
366 PythonDictionary(const PythonDictionary &dict);
367
368 ~PythonDictionary() override;
369
370 static bool Check(PyObject *py_obj);
371
372 // Bring in the no-argument base class version
373 using PythonObject::Reset;
374
375 void Reset(PyRefType type, PyObject *py_obj) override;
376
377 uint32_t GetSize() const;
378
379 PythonList GetKeys() const;
380
381 PythonObject GetItemForKey(const PythonObject &key) const;
382 void SetItemForKey(const PythonObject &key, const PythonObject &value);
383
384 StructuredData::DictionarySP CreateStructuredDictionary() const;
385};
386
387class PythonModule : public PythonObject {
388public:
389 PythonModule();
390 PythonModule(PyRefType type, PyObject *o);
391 PythonModule(const PythonModule &dict);
392
393 ~PythonModule() override;
394
395 static bool Check(PyObject *py_obj);
396
397 static PythonModule BuiltinsModule();
398
399 static PythonModule MainModule();
400
401 static PythonModule AddModule(llvm::StringRef module);
402
403 static PythonModule ImportModule(llvm::StringRef module);
404
405 // Bring in the no-argument base class version
406 using PythonObject::Reset;
407
408 void Reset(PyRefType type, PyObject *py_obj) override;
409
410 PythonDictionary GetDictionary() const;
411};
412
413class PythonCallable : public PythonObject {
414public:
415 struct ArgInfo {
416 size_t count;
417 bool is_bound_method : 1;
418 bool has_varargs : 1;
419 bool has_kwargs : 1;
420 };
421
422 PythonCallable();
423 PythonCallable(PyRefType type, PyObject *o);
424 PythonCallable(const PythonCallable &dict);
425
426 ~PythonCallable() override;
427
428 static bool Check(PyObject *py_obj);
429
430 // Bring in the no-argument base class version
431 using PythonObject::Reset;
432
433 void Reset(PyRefType type, PyObject *py_obj) override;
434
435 ArgInfo GetNumArguments() const;
436
437 PythonObject operator()();
438
439 PythonObject operator()(std::initializer_list<PyObject *> args);
440
441 PythonObject operator()(std::initializer_list<PythonObject> args);
442
443 template <typename Arg, typename... Args>
444 PythonObject operator()(const Arg &arg, Args... args) {
445 return operator()({arg, args...});
446 }
447};
448
449class PythonFile : public PythonObject {
450public:
451 PythonFile();
452 PythonFile(File &file, const char *mode);
453 PythonFile(const char *path, const char *mode);
454 PythonFile(PyRefType type, PyObject *o);
455
456 ~PythonFile() override;
457
458 static bool Check(PyObject *py_obj);
459
460 using PythonObject::Reset;
461
462 void Reset(PyRefType type, PyObject *py_obj) override;
463 void Reset(File &file, const char *mode);
464
465 static uint32_t GetOptionsFromMode(llvm::StringRef mode);
466
467 bool GetUnderlyingFile(File &file) const;
468};
469
470} // namespace lldb_private
471
472#endif
473
474#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H