[Lldb-commits] [lldb] [lldb/Interpreter] Make ScriptedInterface Object creation more generic (PR #68052)

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Tue Oct 24 10:05:56 PDT 2023


================
@@ -32,6 +32,84 @@ class ScriptedPythonInterface : virtual public ScriptedInterface {
   ScriptedPythonInterface(ScriptInterpreterPythonImpl &interpreter);
   ~ScriptedPythonInterface() override = default;
 
+  template <typename... Args>
+  llvm::Expected<StructuredData::GenericSP>
+  CreatePluginObject(llvm::StringRef class_name,
+                     StructuredData::Generic *script_obj, Args... args) {
+    using namespace python;
+    using Locker = ScriptInterpreterPythonImpl::Locker;
+
+    std::string error_string;
+    if (class_name.empty() &&
+        llvm::StringRef(m_interpreter.GetDictionaryName()).empty() &&
+        !script_obj)
+      return llvm::createStringError(
+          llvm::inconvertibleErrorCode(),
+          "ScriptedPythonInterface::CreatePluginObject - missing script class "
+          "name, dictionary or object.");
+
+    Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+                   Locker::FreeLock);
+
+    PythonObject result = {};
+
+    if (!script_obj) {
+      auto dict =
+          PythonModule::MainModule().ResolveName<python::PythonDictionary>(
+              m_interpreter.GetDictionaryName());
+      auto pfunc =
+          PythonObject::ResolveNameWithDictionary<python::PythonCallable>(
+              class_name, dict);
+
+      if (!pfunc.IsAllocated()) {
+        error_string.append("Could not find script class: ");
+        error_string.append(class_name);
+        return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                       error_string);
+      }
+
+      std::tuple<Args...> original_args = std::forward_as_tuple(args...);
+      auto transformed_args = TransformArgs(original_args);
+
+      llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
+      if (!arg_info) {
+        llvm::handleAllErrors(
+            arg_info.takeError(),
+            [&](PythonException &E) { error_string.append(E.ReadBacktrace()); },
+            [&](const llvm::ErrorInfoBase &E) {
+              error_string.append(E.message());
+            });
+        return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                       error_string);
+      }
+
+      llvm::Expected<PythonObject> expected_return_object =
+          llvm::make_error<llvm::StringError>("Not initialized.",
+                                              llvm::inconvertibleErrorCode());
+
+      std::apply(
+          [&pfunc, &expected_return_object](auto &&...args) {
+            llvm::consumeError(expected_return_object.takeError());
+            expected_return_object = pfunc(args...);
+          },
+          transformed_args);
+
+      if (llvm::Error e = expected_return_object.takeError())
+        return e;
+      result = std::move(expected_return_object.get());
+    } else
+      result = PythonObject(PyRefType::Borrowed,
+                            static_cast<PyObject *>(script_obj->GetValue()));
----------------
JDevlieghere wrote:

This is mostly personal preference, but since this is simpler than the other case, I'd put this one first. That way I can page out the "what if script_obj is not NULL" as I'm reading the bigger block above. 

https://github.com/llvm/llvm-project/pull/68052


More information about the lldb-commits mailing list