File: | tools/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp |
Warning: | line 488, column 7 Access to field 'ob_type' results in a dereference of a null pointer (loaded from variable 'py_obj') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||||
30 | using namespace lldb_private; | |||||
31 | using namespace lldb; | |||||
32 | ||||||
33 | void StructuredPythonObject::Dump(Stream &s, bool pretty_print) const { | |||||
34 | s << "Python Obj: 0x" << GetValue(); | |||||
35 | } | |||||
36 | ||||||
37 | //---------------------------------------------------------------------- | |||||
38 | // PythonObject | |||||
39 | //---------------------------------------------------------------------- | |||||
40 | ||||||
41 | void 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 | ||||||
61 | PyObjectType 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 | ||||||
90 | PythonString 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 | ||||||
99 | PythonString 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 | ||||||
108 | PythonObject | |||||
109 | PythonObject::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 | ||||||
124 | PythonObject 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 | ||||||
152 | bool 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 | ||||||
159 | PythonObject 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 | ||||||
171 | bool PythonObject::IsNone() const { return m_py_obj == Py_None(&_Py_NoneStruct); } | |||||
172 | ||||||
173 | bool PythonObject::IsValid() const { return m_py_obj != nullptr; } | |||||
174 | ||||||
175 | bool PythonObject::IsAllocated() const { return IsValid() && !IsNone(); } | |||||
176 | ||||||
177 | StructuredData::ObjectSP PythonObject::CreateStructuredObject() const { | |||||
178 | switch (GetObjectType()) { | |||||
179 | case PyObjectType::Dictionary: | |||||
180 | return PythonDictionary(PyRefType::Borrowed, m_py_obj) | |||||
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(); | |||||
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 | //---------------------------------------------------------------------- | |||||
204 | PythonBytes::PythonBytes() : PythonObject() {} | |||||
205 | ||||||
206 | PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) : PythonObject() { | |||||
207 | SetBytes(bytes); | |||||
208 | } | |||||
209 | ||||||
210 | PythonBytes::PythonBytes(const uint8_t *bytes, size_t length) : PythonObject() { | |||||
211 | SetBytes(llvm::ArrayRef<uint8_t>(bytes, length)); | |||||
212 | } | |||||
213 | ||||||
214 | PythonBytes::PythonBytes(PyRefType type, PyObject *py_obj) : PythonObject() { | |||||
215 | Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string | |||||
216 | } | |||||
217 | ||||||
218 | PythonBytes::PythonBytes(const PythonBytes &object) : PythonObject(object) {} | |||||
219 | ||||||
220 | PythonBytes::~PythonBytes() {} | |||||
221 | ||||||
222 | bool 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 | ||||||
230 | void 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 | ||||||
245 | llvm::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 | ||||||
256 | size_t PythonBytes::GetSize() const { | |||||
257 | if (!IsValid()) | |||||
258 | return 0; | |||||
259 | return PyBytes_SizePyString_Size(m_py_obj); | |||||
260 | } | |||||
261 | ||||||
262 | void 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 | ||||||
268 | StructuredData::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 | ||||||
277 | PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes) | |||||
278 | : PythonByteArray(bytes.data(), bytes.size()) {} | |||||
279 | ||||||
280 | PythonByteArray::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 | ||||||
285 | PythonByteArray::PythonByteArray(PyRefType type, PyObject *o) { | |||||
286 | Reset(type, o); | |||||
287 | } | |||||
288 | ||||||
289 | PythonByteArray::PythonByteArray(const PythonBytes &object) | |||||
290 | : PythonObject(object) {} | |||||
291 | ||||||
292 | PythonByteArray::~PythonByteArray() {} | |||||
293 | ||||||
294 | bool 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 | ||||||
302 | void 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 | ||||||
317 | llvm::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 | ||||||
326 | size_t PythonByteArray::GetSize() const { | |||||
327 | if (!IsValid()) | |||||
328 | return 0; | |||||
329 | ||||||
330 | return PyByteArray_Size(m_py_obj); | |||||
331 | } | |||||
332 | ||||||
333 | StructuredData::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 | ||||||
345 | PythonString::PythonString(PyRefType type, PyObject *py_obj) : PythonObject() { | |||||
346 | Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string | |||||
347 | } | |||||
348 | ||||||
349 | PythonString::PythonString(const PythonString &object) : PythonObject(object) {} | |||||
350 | ||||||
351 | PythonString::PythonString(llvm::StringRef string) : PythonObject() { | |||||
352 | SetString(string); | |||||
353 | } | |||||
354 | ||||||
355 | PythonString::PythonString(const char *string) : PythonObject() { | |||||
356 | SetString(llvm::StringRef(string)); | |||||
357 | } | |||||
358 | ||||||
359 | PythonString::PythonString() : PythonObject() {} | |||||
360 | ||||||
361 | PythonString::~PythonString() {} | |||||
362 | ||||||
363 | bool 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 | ||||||
376 | void 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)) { | |||||
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)) | |||||
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 | ||||||
397 | llvm::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 | ||||||
414 | size_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 | ||||||
425 | void 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 | ||||||
435 | StructuredData::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 | ||||||
445 | PythonInteger::PythonInteger() : PythonObject() {} | |||||
446 | ||||||
447 | PythonInteger::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 | ||||||
452 | PythonInteger::PythonInteger(const PythonInteger &object) | |||||
453 | : PythonObject(object) {} | |||||
454 | ||||||
455 | PythonInteger::PythonInteger(int64_t value) : PythonObject() { | |||||
456 | SetInteger(value); | |||||
457 | } | |||||
458 | ||||||
459 | PythonInteger::~PythonInteger() {} | |||||
460 | ||||||
461 | bool 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 | ||||||
474 | void 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 | ||||||
504 | int64_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 | ||||||
523 | void PythonInteger::SetInteger(int64_t value) { | |||||
524 | PythonObject::Reset(PyRefType::Owned, PyLong_FromLongLong(value)); | |||||
525 | } | |||||
526 | ||||||
527 | StructuredData::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 | ||||||
537 | PythonList::PythonList(PyInitialValue value) : PythonObject() { | |||||
538 | if (value == PyInitialValue::Empty) | |||||
539 | Reset(PyRefType::Owned, PyList_New(0)); | |||||
540 | } | |||||
541 | ||||||
542 | PythonList::PythonList(int list_size) : PythonObject() { | |||||
543 | Reset(PyRefType::Owned, PyList_New(list_size)); | |||||
544 | } | |||||
545 | ||||||
546 | PythonList::PythonList(PyRefType type, PyObject *py_obj) : PythonObject() { | |||||
547 | Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a list | |||||
548 | } | |||||
549 | ||||||
550 | PythonList::PythonList(const PythonList &list) : PythonObject(list) {} | |||||
551 | ||||||
552 | PythonList::~PythonList() {} | |||||
553 | ||||||
554 | bool 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 | ||||||
560 | void 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 | ||||||
575 | uint32_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 | ||||||
581 | PythonObject 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 | ||||||
587 | void 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 | ||||||
596 | void 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 | ||||||
604 | StructuredData::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 | ||||||
618 | PythonTuple::PythonTuple(PyInitialValue value) : PythonObject() { | |||||
619 | if (value == PyInitialValue::Empty) | |||||
620 | Reset(PyRefType::Owned, PyTuple_New(0)); | |||||
621 | } | |||||
622 | ||||||
623 | PythonTuple::PythonTuple(int tuple_size) : PythonObject() { | |||||
624 | Reset(PyRefType::Owned, PyTuple_New(tuple_size)); | |||||
625 | } | |||||
626 | ||||||
627 | PythonTuple::PythonTuple(PyRefType type, PyObject *py_obj) : PythonObject() { | |||||
628 | Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a tuple | |||||
629 | } | |||||
630 | ||||||
631 | PythonTuple::PythonTuple(const PythonTuple &tuple) : PythonObject(tuple) {} | |||||
632 | ||||||
633 | PythonTuple::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 | ||||||
644 | PythonTuple::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 | ||||||
656 | PythonTuple::~PythonTuple() {} | |||||
657 | ||||||
658 | bool 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 | ||||||
664 | void 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 | ||||||
679 | uint32_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 | ||||||
685 | PythonObject 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 | ||||||
691 | void 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 | ||||||
700 | StructuredData::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) { | |||||
| ||||||
704 | PythonObject obj = GetItemAtIndex(i); | |||||
705 | result->AddItem(obj.CreateStructuredObject()); | |||||
706 | } | |||||
707 | return result; | |||||
708 | } | |||||
709 | ||||||
710 | //---------------------------------------------------------------------- | |||||
711 | // PythonDictionary | |||||
712 | //---------------------------------------------------------------------- | |||||
713 | ||||||
714 | PythonDictionary::PythonDictionary(PyInitialValue value) : PythonObject() { | |||||
715 | if (value == PyInitialValue::Empty) | |||||
716 | Reset(PyRefType::Owned, PyDict_New()); | |||||
717 | } | |||||
718 | ||||||
719 | PythonDictionary::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 | ||||||
724 | PythonDictionary::PythonDictionary(const PythonDictionary &object) | |||||
725 | : PythonObject(object) {} | |||||
726 | ||||||
727 | PythonDictionary::~PythonDictionary() {} | |||||
728 | ||||||
729 | bool 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 | ||||||
736 | void 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 | ||||||
751 | uint32_t PythonDictionary::GetSize() const { | |||||
752 | if (IsValid()) | |||||
753 | return PyDict_Size(m_py_obj); | |||||
754 | return 0; | |||||
755 | } | |||||
756 | ||||||
757 | PythonList PythonDictionary::GetKeys() const { | |||||
758 | if (IsValid()) | |||||
759 | return PythonList(PyRefType::Owned, PyDict_Keys(m_py_obj)); | |||||
760 | return PythonList(PyInitialValue::Invalid); | |||||
761 | } | |||||
762 | ||||||
763 | PythonObject 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(); | |||||
768 | } | |||||
769 | ||||||
770 | void 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 | ||||||
776 | StructuredData::DictionarySP | |||||
777 | PythonDictionary::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) { | |||||
782 | PythonObject key = keys.GetItemAtIndex(i); | |||||
783 | PythonObject value = GetItemForKey(key); | |||||
784 | StructuredData::ObjectSP structured_value = value.CreateStructuredObject(); | |||||
785 | result->AddItem(key.Str().GetString(), structured_value); | |||||
786 | } | |||||
787 | return result; | |||||
788 | } | |||||
789 | ||||||
790 | PythonModule::PythonModule() : PythonObject() {} | |||||
791 | ||||||
792 | PythonModule::PythonModule(PyRefType type, PyObject *py_obj) { | |||||
793 | Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a module | |||||
794 | } | |||||
795 | ||||||
796 | PythonModule::PythonModule(const PythonModule &dict) : PythonObject(dict) {} | |||||
797 | ||||||
798 | PythonModule::~PythonModule() {} | |||||
799 | ||||||
800 | PythonModule PythonModule::BuiltinsModule() { | |||||
801 | #if PY_MAJOR_VERSION2 >= 3 | |||||
802 | return AddModule("builtins"); | |||||
803 | #else | |||||
804 | return AddModule("__builtin__"); | |||||
805 | #endif | |||||
806 | } | |||||
807 | ||||||
808 | PythonModule PythonModule::MainModule() { return AddModule("__main__"); } | |||||
809 | ||||||
810 | PythonModule PythonModule::AddModule(llvm::StringRef module) { | |||||
811 | std::string str = module.str(); | |||||
812 | return PythonModule(PyRefType::Borrowed, PyImport_AddModule(str.c_str())); | |||||
813 | } | |||||
814 | ||||||
815 | PythonModule PythonModule::ImportModule(llvm::StringRef module) { | |||||
816 | std::string str = module.str(); | |||||
817 | return PythonModule(PyRefType::Owned, PyImport_ImportModule(str.c_str())); | |||||
818 | } | |||||
819 | ||||||
820 | bool 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 | ||||||
827 | void 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 | ||||||
842 | PythonDictionary PythonModule::GetDictionary() const { | |||||
843 | return PythonDictionary(PyRefType::Borrowed, PyModule_GetDict(m_py_obj)); | |||||
844 | } | |||||
845 | ||||||
846 | PythonCallable::PythonCallable() : PythonObject() {} | |||||
847 | ||||||
848 | PythonCallable::PythonCallable(PyRefType type, PyObject *py_obj) { | |||||
849 | Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a callable | |||||
850 | } | |||||
851 | ||||||
852 | PythonCallable::PythonCallable(const PythonCallable &callable) | |||||
853 | : PythonObject(callable) {} | |||||
854 | ||||||
855 | PythonCallable::~PythonCallable() {} | |||||
856 | ||||||
857 | bool PythonCallable::Check(PyObject *py_obj) { | |||||
858 | if (!py_obj) | |||||
859 | return false; | |||||
860 | ||||||
861 | return PyCallable_Check(py_obj); | |||||
862 | } | |||||
863 | ||||||
864 | void 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 | ||||||
879 | PythonCallable::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 | ||||||
919 | PythonObject PythonCallable::operator()() { | |||||
920 | return PythonObject(PyRefType::Owned, PyObject_CallObject(m_py_obj, nullptr)); | |||||
921 | } | |||||
922 | ||||||
923 | PythonObject PythonCallable:: | |||||
924 | operator()(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 | ||||||
930 | PythonObject PythonCallable:: | |||||
931 | operator()(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 | ||||||
937 | PythonFile::PythonFile() : PythonObject() {} | |||||
938 | ||||||
939 | PythonFile::PythonFile(File &file, const char *mode) { Reset(file, mode); } | |||||
940 | ||||||
941 | PythonFile::PythonFile(const char *path, const char *mode) { | |||||
942 | lldb_private::File file(path, GetOptionsFromMode(mode)); | |||||
943 | Reset(file, mode); | |||||
944 | } | |||||
945 | ||||||
946 | PythonFile::PythonFile(PyRefType type, PyObject *o) { Reset(type, o); } | |||||
947 | ||||||
948 | PythonFile::~PythonFile() {} | |||||
949 | ||||||
950 | bool 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 | ||||||
977 | void 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 | ||||||
992 | void 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 | ||||||
1010 | uint32_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 | ||||||
1027 | bool 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 |
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 | |
32 | namespace lldb_private { |
33 | |
34 | class PythonBytes; |
35 | class PythonString; |
36 | class PythonList; |
37 | class PythonDictionary; |
38 | class PythonInteger; |
39 | |
40 | class StructuredPythonObject : public StructuredData::Generic { |
41 | public: |
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 | |
58 | private: |
59 | DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject)StructuredPythonObject(const StructuredPythonObject &) = delete ; const StructuredPythonObject &operator=(const StructuredPythonObject &) = delete; |
60 | }; |
61 | |
62 | enum 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 | |
77 | enum 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 | |
84 | enum class PyInitialValue { Invalid, Empty }; |
85 | |
86 | class PythonObject { |
87 | public: |
88 | PythonObject() : m_py_obj(nullptr) {} |
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 | |
200 | protected: |
201 | PyObject *m_py_obj; |
202 | }; |
203 | |
204 | class PythonBytes : public PythonObject { |
205 | public: |
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 | |
230 | class PythonByteArray : public PythonObject { |
231 | public: |
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 | |
256 | class PythonString : public PythonObject { |
257 | public: |
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 | |
282 | class PythonInteger : public PythonObject { |
283 | public: |
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 | |
305 | class PythonList : public PythonObject { |
306 | public: |
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 | |
333 | class PythonTuple : public PythonObject { |
334 | public: |
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 | |
361 | class PythonDictionary : public PythonObject { |
362 | public: |
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 | |
387 | class PythonModule : public PythonObject { |
388 | public: |
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 | |
413 | class PythonCallable : public PythonObject { |
414 | public: |
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 | |
449 | class PythonFile : public PythonObject { |
450 | public: |
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 |