diff options
Diffstat (limited to 'lldb/source/Plugins/ScriptInterpreter/Python')
-rw-r--r-- | lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp | 85 | ||||
-rw-r--r-- | lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h | 19 |
2 files changed, 80 insertions, 24 deletions
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp index c3588f6ec33..4d77e552246 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp @@ -22,6 +22,7 @@ #include "lldb/Utility/Stream.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Errno.h" @@ -1012,8 +1013,6 @@ operator()(std::initializer_list<PythonObject> args) { PythonFile::PythonFile() : PythonObject() {} -PythonFile::PythonFile(File &file, const char *mode) { Reset(file, mode); } - PythonFile::PythonFile(PyRefType type, PyObject *o) { Reset(type, o); } PythonFile::~PythonFile() {} @@ -1063,25 +1062,6 @@ void PythonFile::Reset(PyRefType type, PyObject *py_obj) { PythonObject::Reset(PyRefType::Borrowed, result.get()); } -void PythonFile::Reset(File &file, const char *mode) { - if (!file.IsValid()) { - Reset(); - return; - } - - char *cmode = const_cast<char *>(mode); -#if PY_MAJOR_VERSION >= 3 - Reset(PyRefType::Owned, PyFile_FromFd(file.GetDescriptor(), nullptr, cmode, - -1, nullptr, "ignore", nullptr, 0)); -#else - // Read through the Python source, doesn't seem to modify these strings - Reset(PyRefType::Owned, - PyFile_FromFile(file.GetStream(), const_cast<char *>(""), cmode, - nullptr)); -#endif -} - - FileUP PythonFile::GetUnderlyingFile() const { if (!IsValid()) return nullptr; @@ -1238,6 +1218,13 @@ public: return base_error; }; + PyObject *GetPythonObject() const { + assert(m_py_obj.IsValid()); + return m_py_obj.get(); + } + + static bool classof(const File *file) = delete; + protected: PythonFile m_py_obj; bool m_borrowed; @@ -1252,7 +1239,14 @@ public: SimplePythonFile(const PythonFile &file, bool borrowed, int fd, File::OpenOptions options) : OwnedPythonFile(file, borrowed, fd, options, false) {} + + static char ID; + bool isA(const void *classID) const override { + return classID == &ID || NativeFile::isA(classID); + } + static bool classof(const File *file) { return file->isA(&ID); } }; +char SimplePythonFile::ID = 0; } // namespace #if PY_MAJOR_VERSION >= 3 @@ -1321,7 +1315,18 @@ public: return Status(); } + Expected<File::OpenOptions> GetOptions() const override { + GIL takeGIL; + return GetOptionsForPyObject(m_py_obj); + } + + static char ID; + bool isA(const void *classID) const override { + return classID == &ID || File::isA(classID); + } + static bool classof(const File *file) { return file->isA(&ID); } }; +char PythonIOFile::ID = 0; } // namespace namespace { @@ -1542,4 +1547,42 @@ PythonFile::ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed) { #endif } +Expected<PythonFile> PythonFile::FromFile(File &file, const char *mode) { + if (!file.IsValid()) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "invalid file"); + + if (auto *simple = llvm::dyn_cast<SimplePythonFile>(&file)) + return Retain<PythonFile>(simple->GetPythonObject()); +#if PY_MAJOR_VERSION >= 3 + if (auto *pythonio = llvm::dyn_cast<PythonIOFile>(&file)) + return Retain<PythonFile>(pythonio->GetPythonObject()); +#endif + + if (!mode) { + auto m = file.GetOpenMode(); + if (!m) + return m.takeError(); + mode = m.get(); + } + + PyObject *file_obj; +#if PY_MAJOR_VERSION >= 3 + file_obj = PyFile_FromFd(file.GetDescriptor(), nullptr, mode, -1, nullptr, + "ignore", nullptr, 0); +#else + // Read through the Python source, doesn't seem to modify these strings + char *cmode = const_cast<char *>(mode); + // We pass ::flush instead of ::fclose here so we borrow the FILE* -- + // the lldb_private::File still owns it. + file_obj = + PyFile_FromFile(file.GetStream(), const_cast<char *>(""), cmode, ::fflush); +#endif + + if (!file_obj) + return exception(); + + return Take<PythonFile>(file_obj); +} + #endif diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h index a26b64a48d7..b794810c1b7 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h @@ -638,7 +638,7 @@ public: void Reset(PyRefType type, PyObject *py_obj) override; ArgInfo GetNumArguments() const; - + // If the callable is a Py_Class, then find the number of arguments // of the __init__ method. ArgInfo GetNumInitArguments() const; @@ -658,7 +658,6 @@ public: class PythonFile : public PythonObject { public: PythonFile(); - PythonFile(File &file, const char *mode); PythonFile(PyRefType type, PyObject *o); ~PythonFile() override; @@ -668,7 +667,21 @@ public: using PythonObject::Reset; void Reset(PyRefType type, PyObject *py_obj) override; - void Reset(File &file, const char *mode); + + static llvm::Expected<PythonFile> FromFile(File &file, + const char *mode = nullptr); + + // FIXME delete this after FILE* typemaps are deleted + // and ScriptInterpreterPython is fixed + PythonFile(File &file, const char *mode = nullptr) { + auto f = FromFile(file, mode); + if (f) + *this = std::move(f.get()); + else { + Reset(); + llvm::consumeError(f.takeError()); + } + } lldb::FileUP GetUnderlyingFile() const; |