diff options
author | Med Ismail Bennani <ismail@bennani.ma> | 2023-05-22 13:52:09 -0700 |
---|---|---|
committer | Med Ismail Bennani <ismail@bennani.ma> | 2023-05-22 16:14:00 -0700 |
commit | 1370a1cb5b97ecfc4fd2cb550159db9c9ebd3a68 (patch) | |
tree | a281d98fa2d451a04b2b657c02ee19a98c674e3c /lldb/source/Plugins/ScriptInterpreter/Python | |
parent | 01c5ec3d6209875de05de94cd7923c4e462c3317 (diff) | |
download | llvm-1370a1cb5b97ecfc4fd2cb550159db9c9ebd3a68.zip llvm-1370a1cb5b97ecfc4fd2cb550159db9c9ebd3a68.tar.gz llvm-1370a1cb5b97ecfc4fd2cb550159db9c9ebd3a68.tar.bz2 |
[lldb] Add support for negative integer to {SB,}StructuredData
This patch refactors the `StructuredData::Integer` class to make it
templated, makes it private and adds 2 public specialization for both
`int64_t` & `uint64_t` with a public type aliases, respectively
`SignedInteger` & `UnsignedInteger`.
It adds new getter for signed and unsigned interger values to the
`StructuredData::Object` base class and changes the implementation of
`StructuredData::Array::GetItemAtIndexAsInteger` and
`StructuredData::Dictionary::GetValueForKeyAsInteger` to support signed
and unsigned integers.
This patch also adds 2 new `Get{Signed,Unsigned}IntegerValue` to the
`SBStructuredData` class and marks `GetIntegerValue` as deprecated.
Finally, this patch audits all the caller of `StructuredData::Integer`
or `StructuredData::GetIntegerValue` to use the proper type as well the
various tests that uses `SBStructuredData.GetIntegerValue`.
rdar://105575764
Differential Revision: https://reviews.llvm.org/D150485
Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
Diffstat (limited to 'lldb/source/Plugins/ScriptInterpreter/Python')
4 files changed, 46 insertions, 19 deletions
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp index 2291856..eee2f6f 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp @@ -25,6 +25,7 @@ #include "llvm/Support/Errno.h" #include <cstdio> +#include <variant> using namespace lldb_private; using namespace lldb; @@ -101,7 +102,7 @@ Expected<long long> PythonObject::AsLongLong() const { return r; } -Expected<long long> PythonObject::AsUnsignedLongLong() const { +Expected<unsigned long long> PythonObject::AsUnsignedLongLong() const { if (!m_py_obj) return nullDeref(); assert(!PyErr_Occurred()); @@ -117,6 +118,7 @@ Expected<unsigned long long> PythonObject::AsModuloUnsignedLongLong() const { return nullDeref(); assert(!PyErr_Occurred()); unsigned long long r = PyLong_AsUnsignedLongLongMask(m_py_obj); + // FIXME: We should fetch the exception message and hoist it. if (PyErr_Occurred()) return exception(); return r; @@ -267,9 +269,15 @@ StructuredData::ObjectSP PythonObject::CreateStructuredObject() const { case PyObjectType::Boolean: return PythonBoolean(PyRefType::Borrowed, m_py_obj) .CreateStructuredBoolean(); - case PyObjectType::Integer: - return PythonInteger(PyRefType::Borrowed, m_py_obj) - .CreateStructuredInteger(); + case PyObjectType::Integer: { + StructuredData::IntegerSP int_sp = + PythonInteger(PyRefType::Borrowed, m_py_obj).CreateStructuredInteger(); + if (std::holds_alternative<StructuredData::UnsignedIntegerSP>(int_sp)) + return std::get<StructuredData::UnsignedIntegerSP>(int_sp); + if (std::holds_alternative<StructuredData::SignedIntegerSP>(int_sp)) + return std::get<StructuredData::SignedIntegerSP>(int_sp); + return nullptr; + }; case PyObjectType::List: return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray(); case PyObjectType::String: @@ -459,17 +467,32 @@ void PythonInteger::SetInteger(int64_t value) { } StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const { - StructuredData::IntegerSP result(new StructuredData::Integer); - // FIXME this is really not ideal. Errors are silently converted to 0 - // and overflows are silently wrapped. But we'd need larger changes - // to StructuredData to fix it, so that's how it is for now. - llvm::Expected<unsigned long long> value = AsModuloUnsignedLongLong(); - if (!value) { + StructuredData::UnsignedIntegerSP uint_sp = CreateStructuredUnsignedInteger(); + return uint_sp ? StructuredData::IntegerSP(uint_sp) + : CreateStructuredSignedInteger(); +} + +StructuredData::UnsignedIntegerSP +PythonInteger::CreateStructuredUnsignedInteger() const { + StructuredData::UnsignedIntegerSP result = nullptr; + llvm::Expected<unsigned long long> value = AsUnsignedLongLong(); + if (!value) llvm::consumeError(value.takeError()); - result->SetValue(0); - } else { - result->SetValue(value.get()); - } + else + result = std::make_shared<StructuredData::UnsignedInteger>(value.get()); + + return result; +} + +StructuredData::SignedIntegerSP +PythonInteger::CreateStructuredSignedInteger() const { + StructuredData::SignedIntegerSP result = nullptr; + llvm::Expected<long long> value = AsLongLong(); + if (!value) + llvm::consumeError(value.takeError()); + else + result = std::make_shared<StructuredData::SignedInteger>(value.get()); + return result; } diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h index 33092209..61ec4307 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h @@ -354,7 +354,7 @@ public: llvm::Expected<long long> AsLongLong() const; - llvm::Expected<long long> AsUnsignedLongLong() const; + llvm::Expected<unsigned long long> AsUnsignedLongLong() const; // wraps on overflow, instead of raising an error. llvm::Expected<unsigned long long> AsModuloUnsignedLongLong() const; @@ -480,6 +480,10 @@ public: void SetInteger(int64_t value); StructuredData::IntegerSP CreateStructuredInteger() const; + + StructuredData::UnsignedIntegerSP CreateStructuredUnsignedInteger() const; + + StructuredData::SignedIntegerSP CreateStructuredSignedInteger() const; }; class PythonBoolean : public TypedPythonObject<PythonBoolean> { diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp index ad92185..019924f 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp @@ -152,7 +152,7 @@ lldb::offset_t ScriptedProcessPythonInterface::WriteMemoryAtAddress( if (py_error.Fail()) error = py_error; - return obj->GetIntegerValue(LLDB_INVALID_OFFSET); + return obj->GetUnsignedIntegerValue(LLDB_INVALID_OFFSET); } StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() { @@ -173,7 +173,7 @@ lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() { if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return LLDB_INVALID_PROCESS_ID; - return obj->GetIntegerValue(LLDB_INVALID_PROCESS_ID); + return obj->GetUnsignedIntegerValue(LLDB_INVALID_PROCESS_ID); } bool ScriptedProcessPythonInterface::IsAlive() { diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp index 1e0ca39..5603a15 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp @@ -69,7 +69,7 @@ lldb::tid_t ScriptedThreadPythonInterface::GetThreadID() { if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return LLDB_INVALID_THREAD_ID; - return obj->GetIntegerValue(LLDB_INVALID_THREAD_ID); + return obj->GetUnsignedIntegerValue(LLDB_INVALID_THREAD_ID); } std::optional<std::string> ScriptedThreadPythonInterface::GetName() { @@ -89,7 +89,7 @@ lldb::StateType ScriptedThreadPythonInterface::GetState() { if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return eStateInvalid; - return static_cast<StateType>(obj->GetIntegerValue(eStateInvalid)); + return static_cast<StateType>(obj->GetUnsignedIntegerValue(eStateInvalid)); } std::optional<std::string> ScriptedThreadPythonInterface::GetQueue() { |