mib updated this revision to Diff 542217.
mib marked 10 inline comments as done.
mib edited the summary of this revision.
mib added a comment.

Address @bulbazord comments.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155161/new/

https://reviews.llvm.org/D155161

Files:
  lldb/bindings/python/python-typemaps.swig
  lldb/include/lldb/API/SBDebugger.h
  lldb/include/lldb/API/SBDefines.h
  lldb/include/lldb/API/SBProcess.h
  lldb/include/lldb/API/SBStructuredData.h
  lldb/include/lldb/Core/StructuredDataImpl.h
  lldb/include/lldb/Interpreter/ScriptInterpreter.h
  lldb/include/lldb/lldb-types.h
  lldb/source/API/SBProcess.cpp
  lldb/source/API/SBStructuredData.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
  lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py

Index: lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py
===================================================================
--- lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py
+++ lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py
@@ -76,6 +76,40 @@
         # Tests for array data type
         self.array_struct_test(dict_struct)
 
+        s.Clear()
+        self.assertSuccess(example.GetAsJSON(s))
+        py_obj = json.loads(s.GetData())
+        self.assertTrue(py_obj)
+        self.assertIn("key_dict", py_obj)
+
+        py_dict = py_obj["key_dict"]
+        self.assertEqual(py_dict["key_string"], "STRING")
+        self.assertEqual(py_dict["key_uint"], 0xFFFFFFFF00000000)
+        self.assertEqual(py_dict["key_sint"], -42)
+        self.assertEqual(py_dict["key_float"], 2.99)
+        self.assertEqual(py_dict["key_bool"], True)
+        self.assertEqual(py_dict["key_array"], ["23", "arr"])
+
+        class MyRandomClass:
+            payload = "foo"
+
+        py_dict["key_generic"] = MyRandomClass()
+
+        stp = lldb.ScriptObject(py_dict, lldb.eScriptLanguagePython)
+        self.assertEqual(stp.ptr, py_dict)
+
+        sd = lldb.SBStructuredData(stp, self.dbg)
+        self.assertTrue(sd.IsValid())
+        self.assertEqual(sd.GetSize(), len(py_dict))
+
+        generic_sd = sd.GetValueForKey("key_generic")
+        self.assertTrue(generic_sd.IsValid())
+        self.assertEqual(generic_sd.GetType(), lldb.eStructuredDataTypeGeneric)
+
+        my_random_class = generic_sd.GetGenericValue()
+        self.assertTrue(my_random_class)
+        self.assertEqual(my_random_class.payload, MyRandomClass.payload)
+
     def invalid_struct_test(self, example):
         invalid_struct = lldb.SBStructuredData()
         invalid_struct = example.GetValueForKey("invalid_key")
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -83,6 +83,9 @@
                            std::string &error_str,
                            lldb::ThreadPlanSP thread_plan) override;
 
+  StructuredData::ObjectSP
+  CreateStructuredDataFromScriptObject(lldb::ScriptObject obj) override;
+
   bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
                                       Event *event,
                                       bool &script_error) override;
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -1519,6 +1519,16 @@
   return std::make_unique<ScriptedProcessPythonInterface>(*this);
 }
 
+StructuredData::ObjectSP
+ScriptInterpreterPythonImpl::CreateStructuredDataFromScriptObject(
+    lldb::ScriptObject obj) {
+  PythonObject py_obj(PyRefType::Borrowed, static_cast<PyObject *>(obj.ptr));
+  if (!py_obj.IsValid() || py_obj.IsNone())
+    return {};
+  Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
+  return py_obj.CreateStructuredObject();
+}
+
 StructuredData::GenericSP
 ScriptInterpreterPythonImpl::OSPlugin_CreatePluginObject(
     const char *class_name, lldb::ProcessSP process_sp) {
Index: lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
@@ -343,6 +343,15 @@
     return python::Take<PythonObject>(obj);
   }
 
+  llvm::Expected<PythonObject> GetType() const {
+    if (!m_py_obj)
+      return nullDeref();
+    PyObject *obj = PyObject_Type(m_py_obj);
+    if (!obj)
+      return exception();
+    return python::Take<PythonObject>(obj);
+  }
+
   llvm::Expected<bool> IsTrue() {
     if (!m_py_obj)
       return nullDeref();
Index: lldb/source/API/SBStructuredData.cpp
===================================================================
--- lldb/source/API/SBStructuredData.cpp
+++ lldb/source/API/SBStructuredData.cpp
@@ -7,13 +7,16 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/API/SBStructuredData.h"
-#include "lldb/Core/StructuredDataImpl.h"
-#include "lldb/Utility/Instrumentation.h"
 
+#include "lldb/API/SBDebugger.h"
 #include "lldb/API/SBStream.h"
 #include "lldb/API/SBStringList.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/StructuredDataImpl.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
 #include "lldb/Target/StructuredDataPlugin.h"
 #include "lldb/Utility/Event.h"
+#include "lldb/Utility/Instrumentation.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/Utility/Stream.h"
 #include "lldb/Utility/StructuredData.h"
@@ -33,6 +36,22 @@
   LLDB_INSTRUMENT_VA(this, rhs);
 }
 
+SBStructuredData::SBStructuredData(const ScriptObject obj,
+                                   const lldb::SBDebugger &debugger) {
+  LLDB_INSTRUMENT_VA(this, obj, debugger);
+
+  ScriptInterpreter *interpreter =
+      debugger.m_opaque_sp->GetScriptInterpreter(true, obj.lang);
+
+  if (!interpreter)
+    return;
+
+  StructuredDataImplUP impl_up = std::make_unique<StructuredDataImpl>(
+      interpreter->CreateStructuredDataFromScriptObject(obj));
+  if (impl_up && impl_up->IsValid())
+    m_impl_up.reset(impl_up.release());
+}
+
 SBStructuredData::SBStructuredData(const lldb::EventSP &event_sp)
     : m_impl_up(new StructuredDataImpl(event_sp)) {
   LLDB_INSTRUMENT_VA(this, event_sp);
@@ -197,3 +216,9 @@
 
   return m_impl_up->GetStringValue(dst, dst_len);
 }
+
+lldb::ScriptObject SBStructuredData::GetGenericValue() const {
+  LLDB_INSTRUMENT_VA(this);
+
+  return {m_impl_up->GetGenericValue(), eScriptLanguageDefault};
+}
Index: lldb/source/API/SBProcess.cpp
===================================================================
--- lldb/source/API/SBProcess.cpp
+++ lldb/source/API/SBProcess.cpp
@@ -1285,8 +1285,9 @@
   return sb_error;
 }
 
-ScriptedObject SBProcess::GetScriptedImplementation() {
+ScriptObject SBProcess::GetScriptedImplementation() {
   LLDB_INSTRUMENT_VA(this);
   ProcessSP process_sp(GetSP());
-  return (process_sp) ? process_sp->GetImplementation() : nullptr;
+  return ScriptObject((process_sp) ? process_sp->GetImplementation() : nullptr,
+                      eScriptLanguageDefault);
 }
Index: lldb/include/lldb/lldb-types.h
===================================================================
--- lldb/include/lldb/lldb-types.h
+++ lldb/include/lldb/lldb-types.h
@@ -76,6 +76,16 @@
 typedef bool (*ExpressionCancelCallback)(ExpressionEvaluationPhase phase,
                                          void *baton);
 
+typedef void *ScriptObjectPtr;
+
+struct ScriptObject {
+  ScriptObject(ScriptObjectPtr ptr, lldb::ScriptLanguage lang)
+      : ptr(ptr), lang(lang) {}
+
+  const ScriptObjectPtr ptr;
+  lldb::ScriptLanguage lang;
+};
+
 typedef uint64_t addr_t;
 typedef uint64_t user_id_t;
 typedef uint64_t pid_t;
Index: lldb/include/lldb/Interpreter/ScriptInterpreter.h
===================================================================
--- lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -591,6 +591,11 @@
     return *m_scripted_platform_interface_up;
   }
 
+  virtual StructuredData::ObjectSP
+  CreateStructuredDataFromScriptObject(lldb::ScriptObject obj) {
+    return {};
+  }
+
   lldb::DataExtractorSP
   GetDataExtractorFromSBData(const lldb::SBData &data) const;
 
Index: lldb/include/lldb/Core/StructuredDataImpl.h
===================================================================
--- lldb/include/lldb/Core/StructuredDataImpl.h
+++ lldb/include/lldb/Core/StructuredDataImpl.h
@@ -161,6 +161,17 @@
     return (::snprintf(dst, dst_len, "%s", result.data()));
   }
 
+  void *GetGenericValue() const {
+    if (!m_data_sp)
+      return nullptr;
+
+    StructuredData::Generic *generic_data = m_data_sp->GetAsGeneric();
+    if (!generic_data)
+      return nullptr;
+
+    return generic_data->GetValue();
+  }
+
   StructuredData::ObjectSP GetObjectSP() const { return m_data_sp; }
 
 private:
Index: lldb/include/lldb/API/SBStructuredData.h
===================================================================
--- lldb/include/lldb/API/SBStructuredData.h
+++ lldb/include/lldb/API/SBStructuredData.h
@@ -29,6 +29,8 @@
 
   SBStructuredData(const lldb::SBStructuredData &rhs);
 
+  SBStructuredData(const ScriptObject obj, const lldb::SBDebugger &debugger);
+
   ~SBStructuredData();
 
   lldb::SBStructuredData &operator=(const lldb::SBStructuredData &rhs);
@@ -101,6 +103,9 @@
   ///     \a dst in all cases.
   size_t GetStringValue(char *dst, size_t dst_len) const;
 
+  /// Return the generic pointer if this data structure is a generic type.
+  lldb::ScriptObject GetGenericValue() const;
+
 protected:
   friend class SBAttachInfo;
   friend class SBLaunchInfo;
Index: lldb/include/lldb/API/SBProcess.h
===================================================================
--- lldb/include/lldb/API/SBProcess.h
+++ lldb/include/lldb/API/SBProcess.h
@@ -437,7 +437,7 @@
   ///
   lldb::SBError DeallocateMemory(lldb::addr_t ptr);
 
-  lldb::ScriptedObject GetScriptedImplementation();
+  lldb::ScriptObject GetScriptedImplementation();
 
 protected:
   friend class SBAddress;
Index: lldb/include/lldb/API/SBDefines.h
===================================================================
--- lldb/include/lldb/API/SBDefines.h
+++ lldb/include/lldb/API/SBDefines.h
@@ -125,8 +125,6 @@
 
 typedef void (*SBDebuggerDestroyCallback)(lldb::user_id_t debugger_id,
                                           void *baton);
-
-typedef void *ScriptedObject;
 }
 
 #endif // LLDB_API_SBDEFINES_H
Index: lldb/include/lldb/API/SBDebugger.h
===================================================================
--- lldb/include/lldb/API/SBDebugger.h
+++ lldb/include/lldb/API/SBDebugger.h
@@ -484,6 +484,7 @@
   friend class SBListener;
   friend class SBProcess;
   friend class SBSourceManager;
+  friend class SBStructuredData;
   friend class SBTarget;
   friend class SBTrace;
 
Index: lldb/bindings/python/python-typemaps.swig
===================================================================
--- lldb/bindings/python/python-typemaps.swig
+++ lldb/bindings/python/python-typemaps.swig
@@ -59,7 +59,59 @@
   free((char *) $1);
 }
 
-%typemap(out) lldb::ScriptedObject {
+%typemap(in) lldb::ScriptObjectPtr {
+  if ($input == Py_None) {
+    $1 = nullptr;
+  } else {
+    PythonObject obj(PyRefType::Borrowed, $input);
+    if (!obj.IsValid()) {
+      PyErr_SetString(PyExc_TypeError, "Script object is not valid");
+      SWIG_fail;
+    }
+
+    auto lldb_module = PythonModule::Import("lldb");
+    if (!lldb_module) {
+      std::string err_msg = llvm::toString(lldb_module.takeError());
+      PyErr_SetString(PyExc_TypeError, err_msg.c_str());
+      SWIG_fail;
+    }
+
+    auto sb_structured_data_class = lldb_module.get().Get("SBStructuredData");
+    if (!sb_structured_data_class) {
+      std::string err_msg = llvm::toString(sb_structured_data_class.takeError());
+      PyErr_SetString(PyExc_TypeError, err_msg.c_str());
+      SWIG_fail;
+    }
+
+    if (obj.IsInstance(sb_structured_data_class.get())) {
+      $1 = obj.get();
+    } else {
+      auto type = obj.GetType();
+      if (!type) {
+        std::string err_msg = llvm::toString(type.takeError());
+        PyErr_SetString(PyExc_TypeError, err_msg.c_str());
+        SWIG_fail;
+      }
+
+      auto type_name = As<std::string>(type.get().GetAttribute("__name__"));
+      if (!type_name) {
+        std::string err_msg = llvm::toString(type_name.takeError());
+        PyErr_SetString(PyExc_TypeError, err_msg.c_str());
+        SWIG_fail;
+      }
+
+      if (llvm::StringRef(type_name.get()).startswith("SB")) {
+        std::string error_msg = "Input type is invalid: " + type_name.get();
+        PyErr_SetString(PyExc_TypeError, error_msg.c_str());
+        SWIG_fail;
+      } else {
+        $1 = obj.get();
+      }
+    }
+  }
+}
+
+%typemap(out) lldb::ScriptObjectPtr {
   $result = nullptr;
   if (const void* impl = $1)
     $result = (PyObject*) impl;
@@ -71,6 +123,18 @@
   }
 }
 
+%typemap(out) lldb::ScriptObject {
+  $result = nullptr;
+  if (const void* impl = $1.ptr)
+    $result = (PyObject*) impl;
+  if (!$result) {
+    $result = Py_None;
+    Py_INCREF(Py_None);
+  } else {
+    Py_INCREF($result);
+  }
+}
+
 %typemap(out) char** {
   int len;
   int i;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to