Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- PythonDataObjects.cpp ---------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "lldb/Host/Config.h"
10
11
#if LLDB_ENABLE_PYTHON
12
13
#include "PythonDataObjects.h"
14
#include "ScriptInterpreterPython.h"
15
16
#include "lldb/Host/File.h"
17
#include "lldb/Host/FileSystem.h"
18
#include "lldb/Interpreter/ScriptInterpreter.h"
19
#include "lldb/Utility/LLDBLog.h"
20
#include "lldb/Utility/Log.h"
21
#include "lldb/Utility/Stream.h"
22
23
#include "llvm/Support/Casting.h"
24
#include "llvm/Support/ConvertUTF.h"
25
#include "llvm/Support/Errno.h"
26
27
#include <cstdio>
28
#include <variant>
29
30
using namespace lldb_private;
31
using namespace lldb;
32
using namespace lldb_private::python;
33
using llvm::cantFail;
34
using llvm::Error;
35
using llvm::Expected;
36
using llvm::Twine;
37
38
791
template <> Expected<bool> python::As<bool>(Expected<PythonObject> &&obj) {
39
791
  if (!obj)
40
1
    return obj.takeError();
41
790
  return obj.get().IsTrue();
42
791
}
43
44
template <>
45
1.04k
Expected<long long> python::As<long long>(Expected<PythonObject> &&obj) {
46
1.04k
  if (!obj)
47
2
    return obj.takeError();
48
1.04k
  return obj->AsLongLong();
49
1.04k
}
50
51
template <>
52
Expected<unsigned long long>
53
59
python::As<unsigned long long>(Expected<PythonObject> &&obj) {
54
59
  if (!obj)
55
0
    return obj.takeError();
56
59
  return obj->AsUnsignedLongLong();
57
59
}
58
59
template <>
60
8
Expected<std::string> python::As<std::string>(Expected<PythonObject> &&obj) {
61
8
  if (!obj)
62
0
    return obj.takeError();
63
8
  PyObject *str_obj = PyObject_Str(obj.get().get());
64
8
  if (!obj)
65
0
    return llvm::make_error<PythonException>();
66
8
  auto str = Take<PythonString>(str_obj);
67
8
  auto utf8 = str.AsUTF8();
68
8
  if (!utf8)
69
0
    return utf8.takeError();
70
8
  return std::string(utf8.get());
71
8
}
72
73
202k
static bool python_is_finalizing() {
74
#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 7
75
  return _Py_Finalizing != nullptr;
76
#else
77
202k
  return _Py_IsFinalizing();
78
202k
#endif
79
202k
}
80
81
913k
void PythonObject::Reset() {
82
913k
  if (m_py_obj && 
Py_IsInitialized()202k
) {
83
202k
    if (python_is_finalizing()) {
84
      // Leak m_py_obj rather than crashing the process.
85
      // https://docs.python.org/3/c-api/init.html#c.PyGILState_Ensure
86
202k
    } else {
87
202k
      PyGILState_STATE state = PyGILState_Ensure();
88
202k
      Py_DECREF(m_py_obj);
89
202k
      PyGILState_Release(state);
90
202k
    }
91
202k
  }
92
913k
  m_py_obj = nullptr;
93
913k
}
94
95
1.04k
Expected<long long> PythonObject::AsLongLong() const {
96
1.04k
  if (!m_py_obj)
97
0
    return nullDeref();
98
1.04k
  assert(!PyErr_Occurred());
99
1.04k
  long long r = PyLong_AsLongLong(m_py_obj);
100
1.04k
  if (PyErr_Occurred())
101
1
    return exception();
102
1.04k
  return r;
103
1.04k
}
104
105
518
Expected<unsigned long long> PythonObject::AsUnsignedLongLong() const {
106
518
  if (!m_py_obj)
107
0
    return nullDeref();
108
518
  assert(!PyErr_Occurred());
109
518
  long long r = PyLong_AsUnsignedLongLong(m_py_obj);
110
518
  if (PyErr_Occurred())
111
2
    return exception();
112
516
  return r;
113
518
}
114
115
// wraps on overflow, instead of raising an error.
116
0
Expected<unsigned long long> PythonObject::AsModuloUnsignedLongLong() const {
117
0
  if (!m_py_obj)
118
0
    return nullDeref();
119
0
  assert(!PyErr_Occurred());
120
0
  unsigned long long r = PyLong_AsUnsignedLongLongMask(m_py_obj);
121
  // FIXME: We should fetch the exception message and hoist it.
122
0
  if (PyErr_Occurred())
123
0
    return exception();
124
0
  return r;
125
0
}
126
127
0
void StructuredPythonObject::Serialize(llvm::json::OStream &s) const {
128
0
  s.value(llvm::formatv("Python Obj: {0:X}", GetValue()).str());
129
0
}
130
131
// PythonObject
132
133
0
void PythonObject::Dump(Stream &strm) const {
134
0
  if (m_py_obj) {
135
0
    FILE *file = llvm::sys::RetryAfterSignal(nullptr, ::tmpfile);
136
0
    if (file) {
137
0
      ::PyObject_Print(m_py_obj, file, 0);
138
0
      const long length = ftell(file);
139
0
      if (length) {
140
0
        ::rewind(file);
141
0
        std::vector<char> file_contents(length, '\0');
142
0
        const size_t length_read =
143
0
            ::fread(file_contents.data(), 1, file_contents.size(), file);
144
0
        if (length_read > 0)
145
0
          strm.Write(file_contents.data(), length_read);
146
0
      }
147
0
      ::fclose(file);
148
0
    }
149
0
  } else
150
0
    strm.PutCString("NULL");
151
0
}
152
153
1.06k
PyObjectType PythonObject::GetObjectType() const {
154
1.06k
  if (!IsAllocated())
155
0
    return PyObjectType::None;
156
157
1.06k
  if (PythonModule::Check(m_py_obj))
158
0
    return PyObjectType::Module;
159
1.06k
  if (PythonList::Check(m_py_obj))
160
10
    return PyObjectType::List;
161
1.05k
  if (PythonTuple::Check(m_py_obj))
162
0
    return PyObjectType::Tuple;
163
1.05k
  if (PythonDictionary::Check(m_py_obj))
164
116
    return PyObjectType::Dictionary;
165
940
  if (PythonString::Check(m_py_obj))
166
444
    return PyObjectType::String;
167
496
  if (PythonBytes::Check(m_py_obj))
168
5
    return PyObjectType::Bytes;
169
491
  if (PythonByteArray::Check(m_py_obj))
170
1
    return PyObjectType::ByteArray;
171
490
  if (PythonBoolean::Check(m_py_obj))
172
15
    return PyObjectType::Boolean;
173
475
  if (PythonInteger::Check(m_py_obj))
174
458
    return PyObjectType::Integer;
175
17
  if (PythonFile::Check(m_py_obj))
176
0
    return PyObjectType::File;
177
17
  if (PythonCallable::Check(m_py_obj))
178
0
    return PyObjectType::Callable;
179
17
  return PyObjectType::Unknown;
180
17
}
181
182
0
PythonString PythonObject::Repr() const {
183
0
  if (!m_py_obj)
184
0
    return PythonString();
185
0
  PyObject *repr = PyObject_Repr(m_py_obj);
186
0
  if (!repr)
187
0
    return PythonString();
188
0
  return PythonString(PyRefType::Owned, repr);
189
0
}
190
191
992
PythonString PythonObject::Str() const {
192
992
  if (!m_py_obj)
193
0
    return PythonString();
194
992
  PyObject *str = PyObject_Str(m_py_obj);
195
992
  if (!str)
196
0
    return PythonString();
197
992
  return PythonString(PyRefType::Owned, str);
198
992
}
199
200
PythonObject
201
PythonObject::ResolveNameWithDictionary(llvm::StringRef name,
202
492
                                        const PythonDictionary &dict) {
203
492
  size_t dot_pos = name.find('.');
204
492
  llvm::StringRef piece = name.substr(0, dot_pos);
205
492
  PythonObject result = dict.GetItemForKey(PythonString(piece));
206
492
  if (dot_pos == llvm::StringRef::npos) {
207
    // There was no dot, we're done.
208
106
    return result;
209
106
  }
210
211
  // There was a dot.  The remaining portion of the name should be looked up in
212
  // the context of the object that was found in the dictionary.
213
386
  return result.ResolveName(name.substr(dot_pos + 1));
214
492
}
215
216
4.26k
PythonObject PythonObject::ResolveName(llvm::StringRef name) const {
217
  // Resolve the name in the context of the specified object.  If, for example,
218
  // `this` refers to a PyModule, then this will look for `name` in this
219
  // module.  If `this` refers to a PyType, then it will resolve `name` as an
220
  // attribute of that type.  If `this` refers to an instance of an object,
221
  // then it will resolve `name` as the value of the specified field.
222
  //
223
  // This function handles dotted names so that, for example, if `m_py_obj`
224
  // refers to the `sys` module, and `name` == "path.append", then it will find
225
  // the function `sys.path.append`.
226
227
4.26k
  size_t dot_pos = name.find('.');
228
4.26k
  if (dot_pos == llvm::StringRef::npos) {
229
    // No dots in the name, we should be able to find the value immediately as
230
    // an attribute of `m_py_obj`.
231
4.09k
    return GetAttributeValue(name);
232
4.09k
  }
233
234
  // Look up the first piece of the name, and resolve the rest as a child of
235
  // that.
236
173
  PythonObject parent = ResolveName(name.substr(0, dot_pos));
237
173
  if (!parent.IsAllocated())
238
0
    return PythonObject();
239
240
  // Tail recursion.. should be optimized by the compiler
241
173
  return parent.ResolveName(name.substr(dot_pos + 1));
242
173
}
243
244
2
bool PythonObject::HasAttribute(llvm::StringRef attr) const {
245
2
  if (!IsValid())
246
0
    return false;
247
2
  PythonString py_attr(attr);
248
2
  return !!PyObject_HasAttr(m_py_obj, py_attr.get());
249
2
}
250
251
4.09k
PythonObject PythonObject::GetAttributeValue(llvm::StringRef attr) const {
252
4.09k
  if (!IsValid())
253
5
    return PythonObject();
254
255
4.08k
  PythonString py_attr(attr);
256
4.08k
  if (!PyObject_HasAttr(m_py_obj, py_attr.get()))
257
1.05k
    return PythonObject();
258
259
3.03k
  return PythonObject(PyRefType::Owned,
260
3.03k
                      PyObject_GetAttr(m_py_obj, py_attr.get()));
261
4.08k
}
262
263
1.05k
StructuredData::ObjectSP PythonObject::CreateStructuredObject() const {
264
1.05k
  assert(PyGILState_Check());
265
1.05k
  switch (GetObjectType()) {
266
115
  case PyObjectType::Dictionary:
267
115
    return PythonDictionary(PyRefType::Borrowed, m_py_obj)
268
115
        .CreateStructuredDictionary();
269
10
  case PyObjectType::Boolean:
270
10
    return PythonBoolean(PyRefType::Borrowed, m_py_obj)
271
10
        .CreateStructuredBoolean();
272
457
  case PyObjectType::Integer: {
273
457
    StructuredData::IntegerSP int_sp =
274
457
        PythonInteger(PyRefType::Borrowed, m_py_obj).CreateStructuredInteger();
275
457
    if (std::holds_alternative<StructuredData::UnsignedIntegerSP>(int_sp))
276
456
      return std::get<StructuredData::UnsignedIntegerSP>(int_sp);
277
1
    if (std::holds_alternative<StructuredData::SignedIntegerSP>(int_sp))
278
1
      return std::get<StructuredData::SignedIntegerSP>(int_sp);
279
0
    return nullptr;
280
1
  };
281
9
  case PyObjectType::List:
282
9
    return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray();
283
443
  case PyObjectType::String:
284
443
    return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
285
4
  case PyObjectType::Bytes:
286
4
    return PythonBytes(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
287
0
  case PyObjectType::ByteArray:
288
0
    return PythonByteArray(PyRefType::Borrowed, m_py_obj)
289
0
        .CreateStructuredString();
290
0
  case PyObjectType::None:
291
0
    return StructuredData::ObjectSP();
292
17
  default:
293
17
    return StructuredData::ObjectSP(new StructuredPythonObject(
294
17
        PythonObject(PyRefType::Borrowed, m_py_obj)));
295
1.05k
  }
296
1.05k
}
297
298
// PythonString
299
300
0
PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) { SetBytes(bytes); }
301
302
15
PythonBytes::PythonBytes(const uint8_t *bytes, size_t length) {
303
15
  SetBytes(llvm::ArrayRef<uint8_t>(bytes, length));
304
15
}
305
306
533
bool PythonBytes::Check(PyObject *py_obj) {
307
533
  if (!py_obj)
308
0
    return false;
309
533
  return PyBytes_Check(py_obj);
310
533
}
311
312
7
llvm::ArrayRef<uint8_t> PythonBytes::GetBytes() const {
313
7
  if (!IsValid())
314
0
    return llvm::ArrayRef<uint8_t>();
315
316
7
  Py_ssize_t size;
317
7
  char *c;
318
319
7
  PyBytes_AsStringAndSize(m_py_obj, &c, &size);
320
7
  return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
321
7
}
322
323
6
size_t PythonBytes::GetSize() const {
324
6
  if (!IsValid())
325
0
    return 0;
326
6
  return PyBytes_Size(m_py_obj);
327
6
}
328
329
15
void PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes) {
330
15
  const char *data = reinterpret_cast<const char *>(bytes.data());
331
15
  *this = Take<PythonBytes>(PyBytes_FromStringAndSize(data, bytes.size()));
332
15
}
333
334
7
StructuredData::StringSP PythonBytes::CreateStructuredString() const {
335
7
  StructuredData::StringSP result(new StructuredData::String);
336
7
  Py_ssize_t size;
337
7
  char *c;
338
7
  PyBytes_AsStringAndSize(m_py_obj, &c, &size);
339
7
  result->SetValue(std::string(c, size));
340
7
  return result;
341
7
}
342
343
PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes)
344
0
    : PythonByteArray(bytes.data(), bytes.size()) {}
Unexecuted instantiation: lldb_private::python::PythonByteArray::PythonByteArray(llvm::ArrayRef<unsigned char>)
Unexecuted instantiation: lldb_private::python::PythonByteArray::PythonByteArray(llvm::ArrayRef<unsigned char>)
345
346
0
PythonByteArray::PythonByteArray(const uint8_t *bytes, size_t length) {
347
0
  const char *str = reinterpret_cast<const char *>(bytes);
348
0
  *this = Take<PythonByteArray>(PyByteArray_FromStringAndSize(str, length));
349
0
}
350
351
512
bool PythonByteArray::Check(PyObject *py_obj) {
352
512
  if (!py_obj)
353
0
    return false;
354
512
  return PyByteArray_Check(py_obj);
355
512
}
356
357
7
llvm::ArrayRef<uint8_t> PythonByteArray::GetBytes() const {
358
7
  if (!IsValid())
359
0
    return llvm::ArrayRef<uint8_t>();
360
361
7
  char *c = PyByteArray_AsString(m_py_obj);
362
7
  size_t size = GetSize();
363
7
  return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
364
7
}
365
366
13
size_t PythonByteArray::GetSize() const {
367
13
  if (!IsValid())
368
0
    return 0;
369
370
13
  return PyByteArray_Size(m_py_obj);
371
13
}
372
373
0
StructuredData::StringSP PythonByteArray::CreateStructuredString() const {
374
0
  StructuredData::StringSP result(new StructuredData::String);
375
0
  llvm::ArrayRef<uint8_t> bytes = GetBytes();
376
0
  const char *str = reinterpret_cast<const char *>(bytes.data());
377
0
  result->SetValue(std::string(str, bytes.size()));
378
0
  return result;
379
0
}
380
381
// PythonString
382
383
63.1k
Expected<PythonString> PythonString::FromUTF8(llvm::StringRef string) {
384
63.1k
  PyObject *str = PyUnicode_FromStringAndSize(string.data(), string.size());
385
63.1k
  if (!str)
386
0
    return llvm::make_error<PythonException>();
387
63.1k
  return Take<PythonString>(str);
388
63.1k
}
389
390
62.9k
PythonString::PythonString(llvm::StringRef string) { SetString(string); }
391
392
66.0k
bool PythonString::Check(PyObject *py_obj) {
393
66.0k
  if (!py_obj)
394
0
    return false;
395
396
66.0k
  if (PyUnicode_Check(py_obj))
397
65.5k
    return true;
398
510
  return false;
399
66.0k
}
400
401
1.62k
llvm::StringRef PythonString::GetString() const {
402
1.62k
  auto s = AsUTF8();
403
1.62k
  if (!s) {
404
0
    llvm::consumeError(s.takeError());
405
0
    return llvm::StringRef("");
406
0
  }
407
1.62k
  return s.get();
408
1.62k
}
409
410
1.63k
Expected<llvm::StringRef> PythonString::AsUTF8() const {
411
1.63k
  if (!IsValid())
412
0
    return nullDeref();
413
414
1.63k
  Py_ssize_t size;
415
1.63k
  const char *data;
416
417
1.63k
  data = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
418
419
1.63k
  if (!data)
420
0
    return exception();
421
422
1.63k
  return llvm::StringRef(data, size);
423
1.63k
}
424
425
26
size_t PythonString::GetSize() const {
426
26
  if (IsValid()) {
427
26
#if PY_MINOR_VERSION >= 3
428
26
    return PyUnicode_GetLength(m_py_obj);
429
#else
430
    return PyUnicode_GetSize(m_py_obj);
431
#endif
432
26
  }
433
0
  return 0;
434
26
}
435
436
62.9k
void PythonString::SetString(llvm::StringRef string) {
437
62.9k
  auto s = FromUTF8(string);
438
62.9k
  if (!s) {
439
0
    llvm::consumeError(s.takeError());
440
0
    Reset();
441
62.9k
  } else {
442
62.9k
    *this = std::move(s.get());
443
62.9k
  }
444
62.9k
}
445
446
444
StructuredData::StringSP PythonString::CreateStructuredString() const {
447
444
  StructuredData::StringSP result(new StructuredData::String);
448
444
  result->SetValue(GetString());
449
444
  return result;
450
444
}
451
452
// PythonInteger
453
454
1.02k
PythonInteger::PythonInteger(int64_t value) { SetInteger(value); }
455
456
1.96k
bool PythonInteger::Check(PyObject *py_obj) {
457
1.96k
  if (!py_obj)
458
0
    return false;
459
460
  // Python 3 does not have PyInt_Check.  There is only one type of integral
461
  // value, long.
462
1.96k
  return PyLong_Check(py_obj);
463
1.96k
}
464
465
1.02k
void PythonInteger::SetInteger(int64_t value) {
466
1.02k
  *this = Take<PythonInteger>(PyLong_FromLongLong(value));
467
1.02k
}
468
469
459
StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const {
470
459
  StructuredData::UnsignedIntegerSP uint_sp = CreateStructuredUnsignedInteger();
471
459
  return uint_sp ? 
StructuredData::IntegerSP(uint_sp)457
472
459
                 : 
CreateStructuredSignedInteger()2
;
473
459
}
474
475
StructuredData::UnsignedIntegerSP
476
459
PythonInteger::CreateStructuredUnsignedInteger() const {
477
459
  StructuredData::UnsignedIntegerSP result = nullptr;
478
459
  llvm::Expected<unsigned long long> value = AsUnsignedLongLong();
479
459
  if (!value)
480
2
    llvm::consumeError(value.takeError());
481
457
  else
482
457
    result = std::make_shared<StructuredData::UnsignedInteger>(value.get());
483
484
459
  return result;
485
459
}
486
487
StructuredData::SignedIntegerSP
488
2
PythonInteger::CreateStructuredSignedInteger() const {
489
2
  StructuredData::SignedIntegerSP result = nullptr;
490
2
  llvm::Expected<long long> value = AsLongLong();
491
2
  if (!value)
492
0
    llvm::consumeError(value.takeError());
493
2
  else
494
2
    result = std::make_shared<StructuredData::SignedInteger>(value.get());
495
496
2
  return result;
497
2
}
498
499
// PythonBoolean
500
501
2
PythonBoolean::PythonBoolean(bool value) {
502
2
  SetValue(value);
503
2
}
504
505
514
bool PythonBoolean::Check(PyObject *py_obj) {
506
514
  return py_obj ? PyBool_Check(py_obj) : 
false0
;
507
514
}
508
509
15
bool PythonBoolean::GetValue() const {
510
15
  return m_py_obj ? PyObject_IsTrue(m_py_obj) : 
false0
;
511
15
}
512
513
2
void PythonBoolean::SetValue(bool value) {
514
2
  *this = Take<PythonBoolean>(PyBool_FromLong(value));
515
2
}
516
517
10
StructuredData::BooleanSP PythonBoolean::CreateStructuredBoolean() const {
518
10
  StructuredData::BooleanSP result(new StructuredData::Boolean);
519
10
  result->SetValue(GetValue());
520
10
  return result;
521
10
}
522
523
// PythonList
524
525
2
PythonList::PythonList(PyInitialValue value) {
526
2
  if (value == PyInitialValue::Empty)
527
2
    *this = Take<PythonList>(PyList_New(0));
528
2
}
529
530
0
PythonList::PythonList(int list_size) {
531
0
  *this = Take<PythonList>(PyList_New(list_size));
532
0
}
533
534
2.44k
bool PythonList::Check(PyObject *py_obj) {
535
2.44k
  if (!py_obj)
536
0
    return false;
537
2.44k
  return PyList_Check(py_obj);
538
2.44k
}
539
540
299
uint32_t PythonList::GetSize() const {
541
299
  if (IsValid())
542
299
    return PyList_GET_SIZE(m_py_obj);
543
0
  return 0;
544
299
}
545
546
1.20k
PythonObject PythonList::GetItemAtIndex(uint32_t index) const {
547
1.20k
  if (IsValid())
548
1.20k
    return PythonObject(PyRefType::Borrowed, PyList_GetItem(m_py_obj, index));
549
0
  return PythonObject();
550
1.20k
}
551
552
2
void PythonList::SetItemAtIndex(uint32_t index, const PythonObject &object) {
553
2
  if (IsAllocated() && object.IsValid()) {
554
    // PyList_SetItem is documented to "steal" a reference, so we need to
555
    // convert it to an owned reference by incrementing it.
556
2
    Py_INCREF(object.get());
557
2
    PyList_SetItem(m_py_obj, index, object.get());
558
2
  }
559
2
}
560
561
4
void PythonList::AppendItem(const PythonObject &object) {
562
4
  if (IsAllocated() && object.IsValid()) {
563
    // `PyList_Append` does *not* steal a reference, so do not call `Py_INCREF`
564
    // here like we do with `PyList_SetItem`.
565
4
    PyList_Append(m_py_obj, object.get());
566
4
  }
567
4
}
568
569
30
StructuredData::ArraySP PythonList::CreateStructuredArray() const {
570
30
  StructuredData::ArraySP result(new StructuredData::Array);
571
30
  uint32_t count = GetSize();
572
148
  for (uint32_t i = 0; i < count; 
++i118
) {
573
118
    PythonObject obj = GetItemAtIndex(i);
574
118
    result->AddItem(obj.CreateStructuredObject());
575
118
  }
576
30
  return result;
577
30
}
578
579
// PythonTuple
580
581
1
PythonTuple::PythonTuple(PyInitialValue value) {
582
1
  if (value == PyInitialValue::Empty)
583
1
    *this = Take<PythonTuple>(PyTuple_New(0));
584
1
}
585
586
2
PythonTuple::PythonTuple(int tuple_size) {
587
2
  *this = Take<PythonTuple>(PyTuple_New(tuple_size));
588
2
}
589
590
1.98k
PythonTuple::PythonTuple(std::initializer_list<PythonObject> objects) {
591
1.98k
  m_py_obj = PyTuple_New(objects.size());
592
593
1.98k
  uint32_t idx = 0;
594
2.68k
  for (auto object : objects) {
595
2.68k
    if (object.IsValid())
596
2.68k
      SetItemAtIndex(idx, object);
597
2.68k
    idx++;
598
2.68k
  }
599
1.98k
}
600
601
2
PythonTuple::PythonTuple(std::initializer_list<PyObject *> objects) {
602
2
  m_py_obj = PyTuple_New(objects.size());
603
604
2
  uint32_t idx = 0;
605
5
  for (auto py_object : objects) {
606
5
    PythonObject object(PyRefType::Borrowed, py_object);
607
5
    if (object.IsValid())
608
5
      SetItemAtIndex(idx, object);
609
5
    idx++;
610
5
  }
611
2
}
612
613
1.05k
bool PythonTuple::Check(PyObject *py_obj) {
614
1.05k
  if (!py_obj)
615
0
    return false;
616
1.05k
  return PyTuple_Check(py_obj);
617
1.05k
}
618
619
6
uint32_t PythonTuple::GetSize() const {
620
6
  if (IsValid())
621
6
    return PyTuple_GET_SIZE(m_py_obj);
622
0
  return 0;
623
6
}
624
625
11
PythonObject PythonTuple::GetItemAtIndex(uint32_t index) const {
626
11
  if (IsValid())
627
11
    return PythonObject(PyRefType::Borrowed, PyTuple_GetItem(m_py_obj, index));
628
0
  return PythonObject();
629
11
}
630
631
2.69k
void PythonTuple::SetItemAtIndex(uint32_t index, const PythonObject &object) {
632
2.69k
  if (IsAllocated() && object.IsValid()) {
633
    // PyTuple_SetItem is documented to "steal" a reference, so we need to
634
    // convert it to an owned reference by incrementing it.
635
2.69k
    Py_INCREF(object.get());
636
2.69k
    PyTuple_SetItem(m_py_obj, index, object.get());
637
2.69k
  }
638
2.69k
}
639
640
1
StructuredData::ArraySP PythonTuple::CreateStructuredArray() const {
641
1
  StructuredData::ArraySP result(new StructuredData::Array);
642
1
  uint32_t count = GetSize();
643
3
  for (uint32_t i = 0; i < count; 
++i2
) {
644
2
    PythonObject obj = GetItemAtIndex(i);
645
2
    result->AddItem(obj.CreateStructuredObject());
646
2
  }
647
1
  return result;
648
1
}
649
650
// PythonDictionary
651
652
3.66k
PythonDictionary::PythonDictionary(PyInitialValue value) {
653
3.66k
  if (value == PyInitialValue::Empty)
654
62
    *this = Take<PythonDictionary>(PyDict_New());
655
3.66k
}
656
657
14.1k
bool PythonDictionary::Check(PyObject *py_obj) {
658
14.1k
  if (!py_obj)
659
0
    return false;
660
661
14.1k
  return PyDict_Check(py_obj);
662
14.1k
}
663
664
2
uint32_t PythonDictionary::GetSize() const {
665
2
  if (IsValid())
666
2
    return PyDict_Size(m_py_obj);
667
0
  return 0;
668
2
}
669
670
139
PythonList PythonDictionary::GetKeys() const {
671
139
  if (IsValid())
672
139
    return PythonList(PyRefType::Owned, PyDict_Keys(m_py_obj));
673
0
  return PythonList(PyInitialValue::Invalid);
674
139
}
675
676
20.7k
PythonObject PythonDictionary::GetItemForKey(const PythonObject &key) const {
677
20.7k
  auto item = GetItem(key);
678
20.7k
  if (!item) {
679
114
    llvm::consumeError(item.takeError());
680
114
    return PythonObject();
681
114
  }
682
20.6k
  return std::move(item.get());
683
20.7k
}
684
685
Expected<PythonObject>
686
20.7k
PythonDictionary::GetItem(const PythonObject &key) const {
687
20.7k
  if (!IsValid())
688
0
    return nullDeref();
689
20.7k
  PyObject *o = PyDict_GetItemWithError(m_py_obj, key.get());
690
20.7k
  if (PyErr_Occurred())
691
0
    return exception();
692
20.7k
  if (!o)
693
114
    return keyError();
694
20.6k
  return Retain<PythonObject>(o);
695
20.7k
}
696
697
1.47k
Expected<PythonObject> PythonDictionary::GetItem(const Twine &key) const {
698
1.47k
  if (!IsValid())
699
0
    return nullDeref();
700
1.47k
  PyObject *o = PyDict_GetItemString(m_py_obj, NullTerminated(key));
701
1.47k
  if (PyErr_Occurred())
702
0
    return exception();
703
1.47k
  if (!o)
704
0
    return keyError();
705
1.47k
  return Retain<PythonObject>(o);
706
1.47k
}
707
708
Error PythonDictionary::SetItem(const PythonObject &key,
709
38.2k
                                const PythonObject &value) const {
710
38.2k
  if (!IsValid() || !value.IsValid())
711
0
    return nullDeref();
712
38.2k
  int r = PyDict_SetItem(m_py_obj, key.get(), value.get());
713
38.2k
  if (r < 0)
714
0
    return exception();
715
38.2k
  return Error::success();
716
38.2k
}
717
718
Error PythonDictionary::SetItem(const Twine &key,
719
56
                                const PythonObject &value) const {
720
56
  if (!IsValid() || !value.IsValid())
721
0
    return nullDeref();
722
56
  int r = PyDict_SetItemString(m_py_obj, NullTerminated(key), value.get());
723
56
  if (r < 0)
724
0
    return exception();
725
56
  return Error::success();
726
56
}
727
728
void PythonDictionary::SetItemForKey(const PythonObject &key,
729
38.2k
                                     const PythonObject &value) {
730
38.2k
  Error error = SetItem(key, value);
731
38.2k
  if (error)
732
0
    llvm::consumeError(std::move(error));
733
38.2k
}
734
735
StructuredData::DictionarySP
736
139
PythonDictionary::CreateStructuredDictionary() const {
737
139
  StructuredData::DictionarySP result(new StructuredData::Dictionary);
738
139
  PythonList keys(GetKeys());
739
139
  uint32_t num_keys = keys.GetSize();
740
1.03k
  for (uint32_t i = 0; i < num_keys; 
++i898
) {
741
898
    PythonObject key = keys.GetItemAtIndex(i);
742
898
    PythonObject value = GetItemForKey(key);
743
898
    StructuredData::ObjectSP structured_value = value.CreateStructuredObject();
744
898
    result->AddItem(key.Str().GetString(), structured_value);
745
898
  }
746
139
  return result;
747
139
}
748
749
96
PythonModule PythonModule::BuiltinsModule() { return AddModule("builtins"); }
750
751
496
PythonModule PythonModule::MainModule() { return AddModule("__main__"); }
752
753
592
PythonModule PythonModule::AddModule(llvm::StringRef module) {
754
592
  std::string str = module.str();
755
592
  return PythonModule(PyRefType::Borrowed, PyImport_AddModule(str.c_str()));
756
592
}
757
758
22.3k
Expected<PythonModule> PythonModule::Import(const Twine &name) {
759
22.3k
  PyObject *mod = PyImport_ImportModule(NullTerminated(name));
760
22.3k
  if (!mod)
761
0
    return exception();
762
22.3k
  return Take<PythonModule>(mod);
763
22.3k
}
764
765
19.5k
Expected<PythonObject> PythonModule::Get(const Twine &name) {
766
19.5k
  if (!IsValid())
767
0
    return nullDeref();
768
19.5k
  PyObject *dict = PyModule_GetDict(m_py_obj);
769
19.5k
  if (!dict)
770
0
    return exception();
771
19.5k
  PyObject *item = PyDict_GetItemString(dict, NullTerminated(name));
772
19.5k
  if (!item)
773
0
    return exception();
774
19.5k
  return Retain<PythonObject>(item);
775
19.5k
}
776
777
24.0k
bool PythonModule::Check(PyObject *py_obj) {
778
24.0k
  if (!py_obj)
779
0
    return false;
780
781
24.0k
  return PyModule_Check(py_obj);
782
24.0k
}
783
784
7.50k
PythonDictionary PythonModule::GetDictionary() const {
785
7.50k
  if (!IsValid())
786
0
    return PythonDictionary();
787
7.50k
  return Retain<PythonDictionary>(PyModule_GetDict(m_py_obj));
788
7.50k
}
789
790
6.29k
bool PythonCallable::Check(PyObject *py_obj) {
791
6.29k
  if (!py_obj)
792
1.05k
    return false;
793
794
5.23k
  return PyCallable_Check(py_obj);
795
6.29k
}
796
797
#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
798
static const char get_arg_info_script[] = R"(
799
from inspect import signature, Parameter, ismethod
800
from collections import namedtuple
801
ArgInfo = namedtuple('ArgInfo', ['count', 'has_varargs'])
802
def main(f):
803
    count = 0
804
    varargs = False
805
    for parameter in signature(f).parameters.values():
806
        kind = parameter.kind
807
        if kind in (Parameter.POSITIONAL_ONLY,
808
                    Parameter.POSITIONAL_OR_KEYWORD):
809
            count += 1
810
        elif kind == Parameter.VAR_POSITIONAL:
811
            varargs = True
812
        elif kind in (Parameter.KEYWORD_ONLY,
813
                      Parameter.VAR_KEYWORD):
814
            pass
815
        else:
816
            raise Exception(f'unknown parameter kind: {kind}')
817
    return ArgInfo(count, varargs)
818
)";
819
#endif
820
821
332
Expected<PythonCallable::ArgInfo> PythonCallable::GetArgInfo() const {
822
332
  ArgInfo result = {};
823
332
  if (!IsValid())
824
0
    return nullDeref();
825
826
332
#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
827
828
  // no need to synchronize access to this global, we already have the GIL
829
332
  static PythonScript get_arg_info(get_arg_info_script);
830
332
  Expected<PythonObject> pyarginfo = get_arg_info(*this);
831
332
  if (!pyarginfo)
832
0
    return pyarginfo.takeError();
833
332
  long long count =
834
332
      cantFail(As<long long>(pyarginfo.get().GetAttribute("count")));
835
332
  bool has_varargs =
836
332
      cantFail(As<bool>(pyarginfo.get().GetAttribute("has_varargs")));
837
332
  result.max_positional_args = has_varargs ? 
ArgInfo::UNBOUNDED4
:
count328
;
838
839
#else
840
  PyObject *py_func_obj;
841
  bool is_bound_method = false;
842
  bool is_class = false;
843
844
  if (PyType_Check(m_py_obj) || PyClass_Check(m_py_obj)) {
845
    auto init = GetAttribute("__init__");
846
    if (!init)
847
      return init.takeError();
848
    py_func_obj = init.get().get();
849
    is_class = true;
850
  } else {
851
    py_func_obj = m_py_obj;
852
  }
853
854
  if (PyMethod_Check(py_func_obj)) {
855
    py_func_obj = PyMethod_GET_FUNCTION(py_func_obj);
856
    PythonObject im_self = GetAttributeValue("im_self");
857
    if (im_self.IsValid() && !im_self.IsNone())
858
      is_bound_method = true;
859
  } else {
860
    // see if this is a callable object with an __call__ method
861
    if (!PyFunction_Check(py_func_obj)) {
862
      PythonObject __call__ = GetAttributeValue("__call__");
863
      if (__call__.IsValid()) {
864
        auto __callable__ = __call__.AsType<PythonCallable>();
865
        if (__callable__.IsValid()) {
866
          py_func_obj = PyMethod_GET_FUNCTION(__callable__.get());
867
          PythonObject im_self = __callable__.GetAttributeValue("im_self");
868
          if (im_self.IsValid() && !im_self.IsNone())
869
            is_bound_method = true;
870
        }
871
      }
872
    }
873
  }
874
875
  if (!py_func_obj)
876
    return result;
877
878
  PyCodeObject *code = (PyCodeObject *)PyFunction_GET_CODE(py_func_obj);
879
  if (!code)
880
    return result;
881
882
  auto count = code->co_argcount;
883
  bool has_varargs = !!(code->co_flags & CO_VARARGS);
884
  result.max_positional_args =
885
      has_varargs ? ArgInfo::UNBOUNDED
886
                  : (count - (int)is_bound_method) - (int)is_class;
887
888
#endif
889
890
332
  return result;
891
332
}
892
893
constexpr unsigned
894
    PythonCallable::ArgInfo::UNBOUNDED; // FIXME delete after c++17
895
896
413
PythonObject PythonCallable::operator()() {
897
413
  return PythonObject(PyRefType::Owned, PyObject_CallObject(m_py_obj, nullptr));
898
413
}
899
900
PythonObject PythonCallable::
901
0
operator()(std::initializer_list<PyObject *> args) {
902
0
  PythonTuple arg_tuple(args);
903
0
  return PythonObject(PyRefType::Owned,
904
0
                      PyObject_CallObject(m_py_obj, arg_tuple.get()));
905
0
}
906
907
PythonObject PythonCallable::
908
1.98k
operator()(std::initializer_list<PythonObject> args) {
909
1.98k
  PythonTuple arg_tuple(args);
910
1.98k
  return PythonObject(PyRefType::Owned,
911
1.98k
                      PyObject_CallObject(m_py_obj, arg_tuple.get()));
912
1.98k
}
913
914
19.4k
bool PythonFile::Check(PyObject *py_obj) {
915
19.4k
  if (!py_obj)
916
0
    return false;
917
  // In Python 3, there is no `PyFile_Check`, and in fact PyFile is not even a
918
  // first-class object type anymore.  `PyFile_FromFd` is just a thin wrapper
919
  // over `io.open()`, which returns some object derived from `io.IOBase`. As a
920
  // result, the only way to detect a file in Python 3 is to check whether it
921
  // inherits from `io.IOBase`.
922
19.4k
  auto io_module = PythonModule::Import("io");
923
19.4k
  if (!io_module) {
924
0
    llvm::consumeError(io_module.takeError());
925
0
    return false;
926
0
  }
927
19.4k
  auto iobase = io_module.get().Get("IOBase");
928
19.4k
  if (!iobase) {
929
0
    llvm::consumeError(iobase.takeError());
930
0
    return false;
931
0
  }
932
19.4k
  int r = PyObject_IsInstance(py_obj, iobase.get().get());
933
19.4k
  if (r < 0) {
934
0
    llvm::consumeError(exception()); // clear the exception and log it.
935
0
    return false;
936
0
  }
937
19.4k
  return !!r;
938
19.4k
}
939
940
22
const char *PythonException::toCString() const {
941
22
  if (!m_repr_bytes)
942
0
    return "unknown exception";
943
22
  return PyBytes_AS_STRING(m_repr_bytes);
944
22
}
945
946
170
PythonException::PythonException(const char *caller) {
947
170
  assert(PyErr_Occurred());
948
170
  m_exception_type = m_exception = m_traceback = m_repr_bytes = nullptr;
949
170
  PyErr_Fetch(&m_exception_type, &m_exception, &m_traceback);
950
170
  PyErr_NormalizeException(&m_exception_type, &m_exception, &m_traceback);
951
170
  PyErr_Clear();
952
170
  if (m_exception) {
953
170
    PyObject *repr = PyObject_Repr(m_exception);
954
170
    if (repr) {
955
170
      m_repr_bytes = PyUnicode_AsEncodedString(repr, "utf-8", nullptr);
956
170
      if (!m_repr_bytes) {
957
0
        PyErr_Clear();
958
0
      }
959
170
      Py_XDECREF(repr);
960
170
    } else {
961
0
      PyErr_Clear();
962
0
    }
963
170
  }
964
170
  Log *log = GetLog(LLDBLog::Script);
965
170
  if (caller)
966
0
    LLDB_LOGF(log, "%s failed with exception: %s", caller, toCString());
967
170
  else
968
170
    LLDB_LOGF(log, "python exception: %s", toCString());
969
170
}
970
5
void PythonException::Restore() {
971
5
  if (m_exception_type && m_exception) {
972
5
    PyErr_Restore(m_exception_type, m_exception, m_traceback);
973
5
  } else {
974
0
    PyErr_SetString(PyExc_Exception, toCString());
975
0
  }
976
5
  m_exception_type = m_exception = m_traceback = nullptr;
977
5
}
978
979
170
PythonException::~PythonException() {
980
170
  Py_XDECREF(m_exception_type);
981
170
  Py_XDECREF(m_exception);
982
170
  Py_XDECREF(m_traceback);
983
170
  Py_XDECREF(m_repr_bytes);
984
170
}
985
986
15
void PythonException::log(llvm::raw_ostream &OS) const { OS << toCString(); }
987
988
0
std::error_code PythonException::convertToErrorCode() const {
989
0
  return llvm::inconvertibleErrorCode();
990
0
}
991
992
3
bool PythonException::Matches(PyObject *exc) const {
993
3
  return PyErr_GivenExceptionMatches(m_exception_type, exc);
994
3
}
995
996
const char read_exception_script[] = R"(
997
import sys
998
from traceback import print_exception
999
if sys.version_info.major < 3:
1000
  from StringIO import StringIO
1001
else:
1002
  from io import StringIO
1003
def main(exc_type, exc_value, tb):
1004
  f = StringIO()
1005
  print_exception(exc_type, exc_value, tb, file=f)
1006
  return f.getvalue()
1007
)";
1008
1009
8
std::string PythonException::ReadBacktrace() const {
1010
1011
8
  if (!m_traceback)
1012
1
    return toCString();
1013
1014
  // no need to synchronize access to this global, we already have the GIL
1015
7
  static PythonScript read_exception(read_exception_script);
1016
1017
7
  Expected<std::string> backtrace = As<std::string>(
1018
7
      read_exception(m_exception_type, m_exception, m_traceback));
1019
1020
7
  if (!backtrace) {
1021
0
    std::string message =
1022
0
        std::string(toCString()) + "\n" +
1023
0
        "Traceback unavailable, an error occurred while reading it:\n";
1024
0
    return (message + llvm::toString(backtrace.takeError()));
1025
0
  }
1026
1027
7
  return std::move(backtrace.get());
1028
7
}
1029
1030
char PythonException::ID = 0;
1031
1032
llvm::Expected<File::OpenOptions>
1033
168
GetOptionsForPyObject(const PythonObject &obj) {
1034
168
  auto options = File::OpenOptions(0);
1035
168
  auto readable = As<bool>(obj.CallMethod("readable"));
1036
168
  if (!readable)
1037
0
    return readable.takeError();
1038
168
  auto writable = As<bool>(obj.CallMethod("writable"));
1039
168
  if (!writable)
1040
1
    return writable.takeError();
1041
167
  if (readable.get() && 
writable.get()66
)
1042
4
    options |= File::eOpenOptionReadWrite;
1043
163
  else if (writable.get())
1044
101
    options |= File::eOpenOptionWriteOnly;
1045
62
  else if (readable.get())
1046
62
    options |= File::eOpenOptionReadOnly;
1047
167
  return options;
1048
168
}
1049
1050
// Base class template for python files.   All it knows how to do
1051
// is hold a reference to the python object and close or flush it
1052
// when the File is closed.
1053
namespace {
1054
template <typename Base> class OwnedPythonFile : public Base {
1055
public:
1056
  template <typename... Args>
1057
  OwnedPythonFile(const PythonFile &file, bool borrowed, Args... args)
1058
56
      : Base(args...), m_py_obj(file), m_borrowed(borrowed) {
1059
56
    assert(m_py_obj);
1060
56
  }
PythonDataObjects.cpp:(anonymous namespace)::OwnedPythonFile<lldb_private::NativeFile>::OwnedPythonFile<int, lldb_private::File::OpenOptions, bool>(lldb_private::python::PythonFile const&, bool, int, lldb_private::File::OpenOptions, bool)
Line
Count
Source
1058
24
      : Base(args...), m_py_obj(file), m_borrowed(borrowed) {
1059
24
    assert(m_py_obj);
1060
24
  }
PythonDataObjects.cpp:(anonymous namespace)::OwnedPythonFile<lldb_private::File>::OwnedPythonFile<>(lldb_private::python::PythonFile const&, bool)
Line
Count
Source
1058
32
      : Base(args...), m_py_obj(file), m_borrowed(borrowed) {
1059
32
    assert(m_py_obj);
1060
32
  }
1061
1062
56
  ~OwnedPythonFile() override {
1063
56
    assert(m_py_obj);
1064
56
    GIL takeGIL;
1065
56
    Close();
1066
    // we need to ensure the python object is released while we still
1067
    // hold the GIL
1068
56
    m_py_obj.Reset();
1069
56
  }
PythonDataObjects.cpp:(anonymous namespace)::OwnedPythonFile<lldb_private::NativeFile>::~OwnedPythonFile()
Line
Count
Source
1062
24
  ~OwnedPythonFile() override {
1063
24
    assert(m_py_obj);
1064
24
    GIL takeGIL;
1065
24
    Close();
1066
    // we need to ensure the python object is released while we still
1067
    // hold the GIL
1068
24
    m_py_obj.Reset();
1069
24
  }
PythonDataObjects.cpp:(anonymous namespace)::OwnedPythonFile<lldb_private::File>::~OwnedPythonFile()
Line
Count
Source
1062
32
  ~OwnedPythonFile() override {
1063
32
    assert(m_py_obj);
1064
32
    GIL takeGIL;
1065
32
    Close();
1066
    // we need to ensure the python object is released while we still
1067
    // hold the GIL
1068
32
    m_py_obj.Reset();
1069
32
  }
1070
1071
123
  bool IsPythonSideValid() const {
1072
123
    GIL takeGIL;
1073
123
    auto closed = As<bool>(m_py_obj.GetAttribute("closed"));
1074
123
    if (!closed) {
1075
0
      llvm::consumeError(closed.takeError());
1076
0
      return false;
1077
0
    }
1078
123
    return !closed.get();
1079
123
  }
PythonDataObjects.cpp:(anonymous namespace)::OwnedPythonFile<lldb_private::NativeFile>::IsPythonSideValid() const
Line
Count
Source
1071
62
  bool IsPythonSideValid() const {
1072
62
    GIL takeGIL;
1073
62
    auto closed = As<bool>(m_py_obj.GetAttribute("closed"));
1074
62
    if (!closed) {
1075
0
      llvm::consumeError(closed.takeError());
1076
0
      return false;
1077
0
    }
1078
62
    return !closed.get();
1079
62
  }
PythonDataObjects.cpp:(anonymous namespace)::OwnedPythonFile<lldb_private::File>::IsPythonSideValid() const
Line
Count
Source
1071
61
  bool IsPythonSideValid() const {
1072
61
    GIL takeGIL;
1073
61
    auto closed = As<bool>(m_py_obj.GetAttribute("closed"));
1074
61
    if (!closed) {
1075
0
      llvm::consumeError(closed.takeError());
1076
0
      return false;
1077
0
    }
1078
61
    return !closed.get();
1079
61
  }
1080
1081
62
  bool IsValid() const override {
1082
62
    return IsPythonSideValid() && Base::IsValid();
1083
62
  }
PythonDataObjects.cpp:(anonymous namespace)::OwnedPythonFile<lldb_private::NativeFile>::IsValid() const
Line
Count
Source
1081
62
  bool IsValid() const override {
1082
62
    return IsPythonSideValid() && Base::IsValid();
1083
62
  }
Unexecuted instantiation: PythonDataObjects.cpp:(anonymous namespace)::OwnedPythonFile<lldb_private::File>::IsValid() const
1084
1085
62
  Status Close() override {
1086
62
    assert(m_py_obj);
1087
62
    Status py_error, base_error;
1088
62
    GIL takeGIL;
1089
62
    if (!m_borrowed) {
1090
50
      auto r = m_py_obj.CallMethod("close");
1091
50
      if (!r)
1092
0
        py_error = Status(r.takeError());
1093
50
    }
1094
62
    base_error = Base::Close();
1095
62
    if (py_error.Fail())
1096
0
      return py_error;
1097
62
    return base_error;
1098
62
  };
PythonDataObjects.cpp:(anonymous namespace)::OwnedPythonFile<lldb_private::NativeFile>::Close()
Line
Count
Source
1085
30
  Status Close() override {
1086
30
    assert(m_py_obj);
1087
30
    Status py_error, base_error;
1088
30
    GIL takeGIL;
1089
30
    if (!m_borrowed) {
1090
30
      auto r = m_py_obj.CallMethod("close");
1091
30
      if (!r)
1092
0
        py_error = Status(r.takeError());
1093
30
    }
1094
30
    base_error = Base::Close();
1095
30
    if (py_error.Fail())
1096
0
      return py_error;
1097
30
    return base_error;
1098
30
  };
PythonDataObjects.cpp:(anonymous namespace)::OwnedPythonFile<lldb_private::File>::Close()
Line
Count
Source
1085
32
  Status Close() override {
1086
32
    assert(m_py_obj);
1087
32
    Status py_error, base_error;
1088
32
    GIL takeGIL;
1089
32
    if (!m_borrowed) {
1090
20
      auto r = m_py_obj.CallMethod("close");
1091
20
      if (!r)
1092
0
        py_error = Status(r.takeError());
1093
20
    }
1094
32
    base_error = Base::Close();
1095
32
    if (py_error.Fail())
1096
0
      return py_error;
1097
32
    return base_error;
1098
32
  };
1099
1100
7
  PyObject *GetPythonObject() const {
1101
7
    assert(m_py_obj.IsValid());
1102
7
    return m_py_obj.get();
1103
7
  }
PythonDataObjects.cpp:(anonymous namespace)::OwnedPythonFile<lldb_private::NativeFile>::GetPythonObject() const
Line
Count
Source
1100
1
  PyObject *GetPythonObject() const {
1101
1
    assert(m_py_obj.IsValid());
1102
1
    return m_py_obj.get();
1103
1
  }
PythonDataObjects.cpp:(anonymous namespace)::OwnedPythonFile<lldb_private::File>::GetPythonObject() const
Line
Count
Source
1100
6
  PyObject *GetPythonObject() const {
1101
6
    assert(m_py_obj.IsValid());
1102
6
    return m_py_obj.get();
1103
6
  }
1104
1105
  static bool classof(const File *file) = delete;
1106
1107
protected:
1108
  PythonFile m_py_obj;
1109
  bool m_borrowed;
1110
};
1111
} // namespace
1112
1113
// A SimplePythonFile is a OwnedPythonFile that just does all I/O as
1114
// a NativeFile
1115
namespace {
1116
class SimplePythonFile : public OwnedPythonFile<NativeFile> {
1117
public:
1118
  SimplePythonFile(const PythonFile &file, bool borrowed, int fd,
1119
                   File::OpenOptions options)
1120
24
      : OwnedPythonFile(file, borrowed, fd, options, false) {}
1121
1122
  static char ID;
1123
1
  bool isA(const void *classID) const override {
1124
1
    return classID == &ID || 
NativeFile::isA(classID)0
;
1125
1
  }
1126
19.1k
  static bool classof(const File *file) { return file->isA(&ID); }
1127
};
1128
char SimplePythonFile::ID = 0;
1129
} // namespace
1130
1131
namespace {
1132
class PythonBuffer {
1133
public:
1134
  PythonBuffer &operator=(const PythonBuffer &) = delete;
1135
  PythonBuffer(const PythonBuffer &) = delete;
1136
1137
  static Expected<PythonBuffer> Create(PythonObject &obj,
1138
3
                                       int flags = PyBUF_SIMPLE) {
1139
3
    Py_buffer py_buffer = {};
1140
3
    PyObject_GetBuffer(obj.get(), &py_buffer, flags);
1141
3
    if (!py_buffer.obj)
1142
0
      return llvm::make_error<PythonException>();
1143
3
    return PythonBuffer(py_buffer);
1144
3
  }
1145
1146
3
  PythonBuffer(PythonBuffer &&other) {
1147
3
    m_buffer = other.m_buffer;
1148
3
    other.m_buffer.obj = nullptr;
1149
3
  }
1150
1151
6
  ~PythonBuffer() {
1152
6
    if (m_buffer.obj)
1153
3
      PyBuffer_Release(&m_buffer);
1154
6
  }
1155
1156
9
  Py_buffer &get() { return m_buffer; }
1157
1158
private:
1159
  // takes ownership of the buffer.
1160
3
  PythonBuffer(const Py_buffer &py_buffer) : m_buffer(py_buffer) {}
1161
  Py_buffer m_buffer;
1162
};
1163
} // namespace
1164
1165
// Shared methods between TextPythonFile and BinaryPythonFile
1166
namespace {
1167
class PythonIOFile : public OwnedPythonFile<File> {
1168
public:
1169
  PythonIOFile(const PythonFile &file, bool borrowed)
1170
32
      : OwnedPythonFile(file, borrowed) {}
1171
1172
32
  ~PythonIOFile() override { Close(); }
1173
1174
61
  bool IsValid() const override { return IsPythonSideValid(); }
1175
1176
42
  Status Close() override {
1177
42
    assert(m_py_obj);
1178
42
    GIL takeGIL;
1179
42
    if (m_borrowed)
1180
15
      return Flush();
1181
27
    auto r = m_py_obj.CallMethod("close");
1182
27
    if (!r)
1183
3
      return Status(r.takeError());
1184
24
    return Status();
1185
27
  }
1186
1187
28
  Status Flush() override {
1188
28
    GIL takeGIL;
1189
28
    auto r = m_py_obj.CallMethod("flush");
1190
28
    if (!r)
1191
4
      return Status(r.takeError());
1192
24
    return Status();
1193
28
  }
1194
1195
0
  Expected<File::OpenOptions> GetOptions() const override {
1196
0
    GIL takeGIL;
1197
0
    return GetOptionsForPyObject(m_py_obj);
1198
0
  }
1199
1200
  static char ID;
1201
12
  bool isA(const void *classID) const override {
1202
12
    return classID == &ID || 
File::isA(classID)6
;
1203
12
  }
1204
19.1k
  static bool classof(const File *file) { return file->isA(&ID); }
1205
};
1206
char PythonIOFile::ID = 0;
1207
} // namespace
1208
1209
namespace {
1210
class BinaryPythonFile : public PythonIOFile {
1211
protected:
1212
  int m_descriptor;
1213
1214
public:
1215
  BinaryPythonFile(int fd, const PythonFile &file, bool borrowed)
1216
6
      : PythonIOFile(file, borrowed),
1217
6
        m_descriptor(File::DescriptorIsValid(fd) ? 
fd2
1218
6
                                                 : 
File::kInvalidDescriptor4
) {}
1219
1220
2
  int GetDescriptor() const override { return m_descriptor; }
1221
1222
107
  Status Write(const void *buf, size_t &num_bytes) override {
1223
107
    GIL takeGIL;
1224
107
    PyObject *pybuffer_p = PyMemoryView_FromMemory(
1225
107
        const_cast<char *>((const char *)buf), num_bytes, PyBUF_READ);
1226
107
    if (!pybuffer_p)
1227
0
      return Status(llvm::make_error<PythonException>());
1228
107
    auto pybuffer = Take<PythonObject>(pybuffer_p);
1229
107
    num_bytes = 0;
1230
107
    auto bytes_written = As<long long>(m_py_obj.CallMethod("write", pybuffer));
1231
107
    if (!bytes_written)
1232
0
      return Status(bytes_written.takeError());
1233
107
    if (bytes_written.get() < 0)
1234
0
      return Status(".write() method returned a negative number!");
1235
107
    static_assert(sizeof(long long) >= sizeof(size_t), "overflow");
1236
107
    num_bytes = bytes_written.get();
1237
107
    return Status();
1238
107
  }
1239
1240
3
  Status Read(void *buf, size_t &num_bytes) override {
1241
3
    GIL takeGIL;
1242
3
    static_assert(sizeof(long long) >= sizeof(size_t), "overflow");
1243
3
    auto pybuffer_obj =
1244
3
        m_py_obj.CallMethod("read", (unsigned long long)num_bytes);
1245
3
    if (!pybuffer_obj)
1246
0
      return Status(pybuffer_obj.takeError());
1247
3
    num_bytes = 0;
1248
3
    if (pybuffer_obj.get().IsNone()) {
1249
      // EOF
1250
0
      num_bytes = 0;
1251
0
      return Status();
1252
0
    }
1253
3
    auto pybuffer = PythonBuffer::Create(pybuffer_obj.get());
1254
3
    if (!pybuffer)
1255
0
      return Status(pybuffer.takeError());
1256
3
    memcpy(buf, pybuffer.get().get().buf, pybuffer.get().get().len);
1257
3
    num_bytes = pybuffer.get().get().len;
1258
3
    return Status();
1259
3
  }
1260
};
1261
} // namespace
1262
1263
namespace {
1264
class TextPythonFile : public PythonIOFile {
1265
protected:
1266
  int m_descriptor;
1267
1268
public:
1269
  TextPythonFile(int fd, const PythonFile &file, bool borrowed)
1270
26
      : PythonIOFile(file, borrowed),
1271
26
        m_descriptor(File::DescriptorIsValid(fd) ? 
fd2
1272
26
                                                 : 
File::kInvalidDescriptor24
) {}
1273
1274
2
  int GetDescriptor() const override { return m_descriptor; }
1275
1276
206
  Status Write(const void *buf, size_t &num_bytes) override {
1277
206
    GIL takeGIL;
1278
206
    auto pystring =
1279
206
        PythonString::FromUTF8(llvm::StringRef((const char *)buf, num_bytes));
1280
206
    if (!pystring)
1281
0
      return Status(pystring.takeError());
1282
206
    num_bytes = 0;
1283
206
    auto bytes_written =
1284
206
        As<long long>(m_py_obj.CallMethod("write", pystring.get()));
1285
206
    if (!bytes_written)
1286
2
      return Status(bytes_written.takeError());
1287
204
    if (bytes_written.get() < 0)
1288
0
      return Status(".write() method returned a negative number!");
1289
204
    static_assert(sizeof(long long) >= sizeof(size_t), "overflow");
1290
204
    num_bytes = bytes_written.get();
1291
204
    return Status();
1292
204
  }
1293
1294
5
  Status Read(void *buf, size_t &num_bytes) override {
1295
5
    GIL takeGIL;
1296
5
    size_t num_chars = num_bytes / 6;
1297
5
    size_t orig_num_bytes = num_bytes;
1298
5
    num_bytes = 0;
1299
5
    if (orig_num_bytes < 6) {
1300
1
      return Status("can't read less than 6 bytes from a utf8 text stream");
1301
1
    }
1302
4
    auto pystring = As<PythonString>(
1303
4
        m_py_obj.CallMethod("read", (unsigned long long)num_chars));
1304
4
    if (!pystring)
1305
1
      return Status(pystring.takeError());
1306
3
    if (pystring.get().IsNone()) {
1307
      // EOF
1308
0
      return Status();
1309
0
    }
1310
3
    auto stringref = pystring.get().AsUTF8();
1311
3
    if (!stringref)
1312
0
      return Status(stringref.takeError());
1313
3
    num_bytes = stringref.get().size();
1314
3
    memcpy(buf, stringref.get().begin(), num_bytes);
1315
3
    return Status();
1316
3
  }
1317
};
1318
} // namespace
1319
1320
196
llvm::Expected<FileSP> PythonFile::ConvertToFile(bool borrowed) {
1321
196
  if (!IsValid())
1322
0
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
1323
0
                                   "invalid PythonFile");
1324
1325
196
  int fd = PyObject_AsFileDescriptor(m_py_obj);
1326
196
  if (fd < 0) {
1327
28
    PyErr_Clear();
1328
28
    return ConvertToFileForcingUseOfScriptingIOMethods(borrowed);
1329
28
  }
1330
168
  auto options = GetOptionsForPyObject(*this);
1331
168
  if (!options)
1332
1
    return options.takeError();
1333
1334
167
  File::OpenOptions rw =
1335
167
      options.get() & (File::eOpenOptionReadOnly | File::eOpenOptionWriteOnly |
1336
167
                       File::eOpenOptionReadWrite);
1337
167
  if (rw == File::eOpenOptionWriteOnly || 
rw == File::eOpenOptionReadWrite66
) {
1338
    // LLDB and python will not share I/O buffers.  We should probably
1339
    // flush the python buffers now.
1340
105
    auto r = CallMethod("flush");
1341
105
    if (!r)
1342
0
      return r.takeError();
1343
105
  }
1344
1345
167
  FileSP file_sp;
1346
167
  if (borrowed) {
1347
    // In this case we don't need to retain the python
1348
    // object at all.
1349
143
    file_sp = std::make_shared<NativeFile>(fd, options.get(), false);
1350
143
  } else {
1351
24
    file_sp = std::static_pointer_cast<File>(
1352
24
        std::make_shared<SimplePythonFile>(*this, borrowed, fd, options.get()));
1353
24
  }
1354
167
  if (!file_sp->IsValid())
1355
0
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
1356
0
                                   "invalid File");
1357
1358
167
  return file_sp;
1359
167
}
1360
1361
llvm::Expected<FileSP>
1362
32
PythonFile::ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed) {
1363
1364
32
  assert(!PyErr_Occurred());
1365
1366
32
  if (!IsValid())
1367
0
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
1368
0
                                   "invalid PythonFile");
1369
1370
32
  int fd = PyObject_AsFileDescriptor(m_py_obj);
1371
32
  if (fd < 0) {
1372
28
    PyErr_Clear();
1373
28
    fd = File::kInvalidDescriptor;
1374
28
  }
1375
1376
32
  auto io_module = PythonModule::Import("io");
1377
32
  if (!io_module)
1378
0
    return io_module.takeError();
1379
32
  auto textIOBase = io_module.get().Get("TextIOBase");
1380
32
  if (!textIOBase)
1381
0
    return textIOBase.takeError();
1382
32
  auto rawIOBase = io_module.get().Get("RawIOBase");
1383
32
  if (!rawIOBase)
1384
0
    return rawIOBase.takeError();
1385
32
  auto bufferedIOBase = io_module.get().Get("BufferedIOBase");
1386
32
  if (!bufferedIOBase)
1387
0
    return bufferedIOBase.takeError();
1388
1389
32
  FileSP file_sp;
1390
1391
32
  auto isTextIO = IsInstance(textIOBase.get());
1392
32
  if (!isTextIO)
1393
0
    return isTextIO.takeError();
1394
32
  if (isTextIO.get())
1395
26
    file_sp = std::static_pointer_cast<File>(
1396
26
        std::make_shared<TextPythonFile>(fd, *this, borrowed));
1397
1398
32
  auto isRawIO = IsInstance(rawIOBase.get());
1399
32
  if (!isRawIO)
1400
0
    return isRawIO.takeError();
1401
32
  auto isBufferedIO = IsInstance(bufferedIOBase.get());
1402
32
  if (!isBufferedIO)
1403
0
    return isBufferedIO.takeError();
1404
1405
32
  if (isRawIO.get() || isBufferedIO.get()) {
1406
6
    file_sp = std::static_pointer_cast<File>(
1407
6
        std::make_shared<BinaryPythonFile>(fd, *this, borrowed));
1408
6
  }
1409
1410
32
  if (!file_sp)
1411
0
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
1412
0
                                   "python file is neither text nor binary");
1413
1414
32
  if (!file_sp->IsValid())
1415
0
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
1416
0
                                   "invalid File");
1417
1418
32
  return file_sp;
1419
32
}
1420
1421
19.1k
Expected<PythonFile> PythonFile::FromFile(File &file, const char *mode) {
1422
19.1k
  if (!file.IsValid())
1423
0
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
1424
0
                                   "invalid file");
1425
1426
19.1k
  if (auto *simple = llvm::dyn_cast<SimplePythonFile>(&file))
1427
1
    return Retain<PythonFile>(simple->GetPythonObject());
1428
19.1k
  if (auto *pythonio = llvm::dyn_cast<PythonIOFile>(&file))
1429
6
    return Retain<PythonFile>(pythonio->GetPythonObject());
1430
1431
19.1k
  if (!mode) {
1432
18
    auto m = file.GetOpenMode();
1433
18
    if (!m)
1434
0
      return m.takeError();
1435
18
    mode = m.get();
1436
18
  }
1437
1438
19.1k
  PyObject *file_obj;
1439
19.1k
  file_obj = PyFile_FromFd(file.GetDescriptor(), nullptr, mode, -1, nullptr,
1440
19.1k
                           "ignore", nullptr, /*closefd=*/0);
1441
1442
19.1k
  if (!file_obj)
1443
0
    return exception();
1444
1445
19.1k
  return Take<PythonFile>(file_obj);
1446
19.1k
}
1447
1448
343
Error PythonScript::Init() {
1449
343
  if (function.IsValid())
1450
288
    return Error::success();
1451
1452
55
  PythonDictionary globals(PyInitialValue::Empty);
1453
55
  auto builtins = PythonModule::BuiltinsModule();
1454
55
  if (Error error = globals.SetItem("__builtins__", builtins))
1455
0
    return error;
1456
55
  PyObject *o =
1457
55
      PyRun_String(script, Py_file_input, globals.get(), globals.get());
1458
55
  if (!o)
1459
0
    return exception();
1460
55
  Take<PythonObject>(o);
1461
55
  auto f = As<PythonCallable>(globals.GetItem("main"));
1462
55
  if (!f)
1463
0
    return f.takeError();
1464
55
  function = std::move(f.get());
1465
1466
55
  return Error::success();
1467
55
}
1468
1469
llvm::Expected<PythonObject>
1470
python::runStringOneLine(const llvm::Twine &string,
1471
                         const PythonDictionary &globals,
1472
5.81k
                         const PythonDictionary &locals) {
1473
5.81k
  if (!globals.IsValid() || !locals.IsValid())
1474
0
    return nullDeref();
1475
1476
5.81k
  PyObject *code =
1477
5.81k
      Py_CompileString(NullTerminated(string), "<string>", Py_eval_input);
1478
5.81k
  if (!code) {
1479
1
    PyErr_Clear();
1480
1
    code =
1481
1
        Py_CompileString(NullTerminated(string), "<string>", Py_single_input);
1482
1
  }
1483
5.81k
  if (!code)
1484
0
    return exception();
1485
5.81k
  auto code_ref = Take<PythonObject>(code);
1486
1487
5.81k
  PyObject *result = PyEval_EvalCode(code, globals.get(), locals.get());
1488
1489
5.81k
  if (!result)
1490
3
    return exception();
1491
1492
5.80k
  return Take<PythonObject>(result);
1493
5.81k
}
1494
1495
llvm::Expected<PythonObject>
1496
python::runStringMultiLine(const llvm::Twine &string,
1497
                           const PythonDictionary &globals,
1498
276
                           const PythonDictionary &locals) {
1499
276
  if (!globals.IsValid() || !locals.IsValid())
1500
0
    return nullDeref();
1501
276
  PyObject *result = PyRun_String(NullTerminated(string), Py_file_input,
1502
276
                                  globals.get(), locals.get());
1503
276
  if (!result)
1504
5
    return exception();
1505
271
  return Take<PythonObject>(result);
1506
276
}
1507
1508
#endif