[Lldb-commits] [lldb] [lldb] Unifying Scripted Affordance Interfaces (PR #68052)

Med Ismail Bennani via lldb-commits lldb-commits at lists.llvm.org
Mon Oct 2 16:51:34 PDT 2023


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

None

>From 5d1aa93345835d3614caffa8dd3041d995144e7e Mon Sep 17 00:00:00 2001
From: Med Ismail Bennani <ismail at bennani.ma>
Date: Thu, 31 Aug 2023 13:13:57 +0100
Subject: [PATCH 1/6] [lldb] Move ScriptInterpreter Interfaces to subdirectory
 (NFC)

As we're consolidating and  streamlining the various scripting
affordances of lldb, we keep creating new interface files.

This patch groups all the current interface files into a separate sub
directory called `Interfaces` both in the core `Interpreter` directory
and the `ScriptInterpreter` plugin directory.

Differential Revision: https://reviews.llvm.org/D158833

Signed-off-by: Med Ismail Bennani <ismail at bennani.ma>
---
 .../{ => Interfaces}/ScriptedInterface.h      |  6 +--
 .../ScriptedPlatformInterface.h               |  8 +--
 .../ScriptedProcessInterface.h                | 38 ++------------
 .../Interfaces/ScriptedThreadInterface.h      | 52 +++++++++++++++++++
 .../lldb/Interpreter/ScriptInterpreter.h      |  9 +++-
 .../ScriptInterpreter/Python/CMakeLists.txt   |  7 ++-
 .../Python/Interfaces/CMakeLists.txt          | 38 ++++++++++++++
 .../ScriptedPlatformPythonInterface.cpp       |  6 +--
 .../ScriptedPlatformPythonInterface.h         |  8 +--
 .../ScriptedProcessPythonInterface.cpp        |  8 +--
 .../ScriptedProcessPythonInterface.h          |  8 +--
 .../ScriptedPythonInterface.cpp               |  4 +-
 .../ScriptedPythonInterface.h                 | 15 +++---
 .../ScriptedThreadPythonInterface.cpp         |  6 +--
 .../ScriptedThreadPythonInterface.h           |  8 +--
 .../Python/ScriptInterpreterPython.cpp        | 10 +++-
 .../Python/ScriptInterpreterPythonImpl.h      |  1 +
 17 files changed, 151 insertions(+), 81 deletions(-)
 rename lldb/include/lldb/Interpreter/{ => Interfaces}/ScriptedInterface.h (93%)
 rename lldb/include/lldb/Interpreter/{ => Interfaces}/ScriptedPlatformInterface.h (85%)
 rename lldb/include/lldb/Interpreter/{ => Interfaces}/ScriptedProcessInterface.h (68%)
 create mode 100644 lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadInterface.h
 create mode 100644 lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt
 rename lldb/source/Plugins/ScriptInterpreter/Python/{ => Interfaces}/ScriptedPlatformPythonInterface.cpp (97%)
 rename lldb/source/Plugins/ScriptInterpreter/Python/{ => Interfaces}/ScriptedPlatformPythonInterface.h (80%)
 rename lldb/source/Plugins/ScriptInterpreter/Python/{ => Interfaces}/ScriptedProcessPythonInterface.cpp (97%)
 rename lldb/source/Plugins/ScriptInterpreter/Python/{ => Interfaces}/ScriptedProcessPythonInterface.h (86%)
 rename lldb/source/Plugins/ScriptInterpreter/Python/{ => Interfaces}/ScriptedPythonInterface.cpp (98%)
 rename lldb/source/Plugins/ScriptInterpreter/Python/{ => Interfaces}/ScriptedPythonInterface.h (95%)
 rename lldb/source/Plugins/ScriptInterpreter/Python/{ => Interfaces}/ScriptedThreadPythonInterface.cpp (97%)
 rename lldb/source/Plugins/ScriptInterpreter/Python/{ => Interfaces}/ScriptedThreadPythonInterface.h (81%)

diff --git a/lldb/include/lldb/Interpreter/ScriptedInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h
similarity index 93%
rename from lldb/include/lldb/Interpreter/ScriptedInterface.h
rename to lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h
index ab6142593264374..948f763e95ecea4 100644
--- a/lldb/include/lldb/Interpreter/ScriptedInterface.h
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLDB_INTERPRETER_SCRIPTEDINTERFACE_H
-#define LLDB_INTERPRETER_SCRIPTEDINTERFACE_H
+#ifndef LLDB_INTERPRETER_INTERFACES_SCRIPTEDINTERFACE_H
+#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDINTERFACE_H
 
 #include "lldb/Core/StructuredDataImpl.h"
 #include "lldb/Target/ExecutionContext.h"
@@ -74,4 +74,4 @@ class ScriptedInterface {
   StructuredData::GenericSP m_object_instance_sp;
 };
 } // namespace lldb_private
-#endif // LLDB_INTERPRETER_SCRIPTEDINTERFACE_H
+#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDINTERFACE_H
diff --git a/lldb/include/lldb/Interpreter/ScriptedPlatformInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h
similarity index 85%
rename from lldb/include/lldb/Interpreter/ScriptedPlatformInterface.h
rename to lldb/include/lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h
index 2db1fef0be721e6..c687cabfe0c1278 100644
--- a/lldb/include/lldb/Interpreter/ScriptedPlatformInterface.h
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h
@@ -6,11 +6,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLDB_INTERPRETER_SCRIPTEDPLATFORMINTERFACE_H
-#define LLDB_INTERPRETER_SCRIPTEDPLATFORMINTERFACE_H
+#ifndef LLDB_INTERPRETER_INTERFACES_SCRIPTEDPLATFORMINTERFACE_H
+#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDPLATFORMINTERFACE_H
 
 #include "lldb/Core/StructuredDataImpl.h"
-#include "lldb/Interpreter/ScriptedInterface.h"
+#include "lldb/Interpreter/Interfaces/ScriptedInterface.h"
 
 #include "lldb/lldb-private.h"
 
@@ -46,4 +46,4 @@ class ScriptedPlatformInterface : virtual public ScriptedInterface {
 };
 } // namespace lldb_private
 
-#endif // LLDB_INTERPRETER_SCRIPTEDPLATFORMINTERFACE_H
+#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDPLATFORMINTERFACE_H
diff --git a/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedProcessInterface.h
similarity index 68%
rename from lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
rename to lldb/include/lldb/Interpreter/Interfaces/ScriptedProcessInterface.h
index 210b1081cddcd79..68756c4d9ac858d 100644
--- a/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedProcessInterface.h
@@ -6,11 +6,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLDB_INTERPRETER_SCRIPTEDPROCESSINTERFACE_H
-#define LLDB_INTERPRETER_SCRIPTEDPROCESSINTERFACE_H
+#ifndef LLDB_INTERPRETER_INTERFACES_SCRIPTEDPROCESSINTERFACE_H
+#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDPROCESSINTERFACE_H
 
+#include "ScriptedInterface.h"
 #include "lldb/Core/StructuredDataImpl.h"
-#include "lldb/Interpreter/ScriptedInterface.h"
 #include "lldb/Target/MemoryRegionInfo.h"
 
 #include "lldb/lldb-private.h"
@@ -80,36 +80,6 @@ class ScriptedProcessInterface : virtual public ScriptedInterface {
     return {};
   }
 };
-
-class ScriptedThreadInterface : virtual public ScriptedInterface {
-public:
-  StructuredData::GenericSP
-  CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx,
-                     StructuredData::DictionarySP args_sp,
-                     StructuredData::Generic *script_obj = nullptr) override {
-    return {};
-  }
-
-  virtual lldb::tid_t GetThreadID() { return LLDB_INVALID_THREAD_ID; }
-
-  virtual std::optional<std::string> GetName() { return std::nullopt; }
-
-  virtual lldb::StateType GetState() { return lldb::eStateInvalid; }
-
-  virtual std::optional<std::string> GetQueue() { return std::nullopt; }
-
-  virtual StructuredData::DictionarySP GetStopReason() { return {}; }
-
-  virtual StructuredData::ArraySP GetStackFrames() { return {}; }
-
-  virtual StructuredData::DictionarySP GetRegisterInfo() { return {}; }
-
-  virtual std::optional<std::string> GetRegisterContext() {
-    return std::nullopt;
-  }
-
-  virtual StructuredData::ArraySP GetExtendedInfo() { return {}; }
-};
 } // namespace lldb_private
 
-#endif // LLDB_INTERPRETER_SCRIPTEDPROCESSINTERFACE_H
+#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDPROCESSINTERFACE_H
diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadInterface.h
new file mode 100644
index 000000000000000..781df51a213229a
--- /dev/null
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadInterface.h
@@ -0,0 +1,52 @@
+//===-- ScriptedThreadInterface.h -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_INTERPRETER_INTERFACES_SCRIPTEDTHREADINTERFACE_H
+#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDTHREADINTERFACE_H
+
+#include "ScriptedInterface.h"
+#include "lldb/Core/StructuredDataImpl.h"
+
+#include "lldb/lldb-private.h"
+
+#include <optional>
+#include <string>
+
+namespace lldb_private {
+class ScriptedThreadInterface : virtual public ScriptedInterface {
+public:
+  StructuredData::GenericSP
+  CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx,
+                     StructuredData::DictionarySP args_sp,
+                     StructuredData::Generic *script_obj = nullptr) override {
+    return {};
+  }
+
+  virtual lldb::tid_t GetThreadID() { return LLDB_INVALID_THREAD_ID; }
+
+  virtual std::optional<std::string> GetName() { return std::nullopt; }
+
+  virtual lldb::StateType GetState() { return lldb::eStateInvalid; }
+
+  virtual std::optional<std::string> GetQueue() { return std::nullopt; }
+
+  virtual StructuredData::DictionarySP GetStopReason() { return {}; }
+
+  virtual StructuredData::ArraySP GetStackFrames() { return {}; }
+
+  virtual StructuredData::DictionarySP GetRegisterInfo() { return {}; }
+
+  virtual std::optional<std::string> GetRegisterContext() {
+    return std::nullopt;
+  }
+
+  virtual StructuredData::ArraySP GetExtendedInfo() { return {}; }
+};
+} // namespace lldb_private
+
+#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDTHREADINTERFACE_H
diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
index 7ee251e2087502e..eacd10d5279be6f 100644
--- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -21,9 +21,10 @@
 #include "lldb/Core/ThreadedCommunication.h"
 #include "lldb/Host/PseudoTerminal.h"
 #include "lldb/Host/StreamFile.h"
+#include "lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h"
+#include "lldb/Interpreter/Interfaces/ScriptedProcessInterface.h"
+#include "lldb/Interpreter/Interfaces/ScriptedThreadInterface.h"
 #include "lldb/Interpreter/ScriptObject.h"
-#include "lldb/Interpreter/ScriptedPlatformInterface.h"
-#include "lldb/Interpreter/ScriptedProcessInterface.h"
 #include "lldb/Utility/Broadcaster.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/Utility/StructuredData.h"
@@ -588,6 +589,10 @@ class ScriptInterpreter : public PluginInterface {
     return std::make_unique<ScriptedProcessInterface>();
   }
 
+  virtual lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() {
+    return std::make_shared<ScriptedThreadInterface>();
+  }
+
   ScriptedPlatformInterface &GetScriptedPlatformInterface() {
     return *m_scripted_platform_interface_up;
   }
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt b/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt
index 72361166964241a..7523d65abf0f802 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt
@@ -19,14 +19,12 @@ if (LLDB_ENABLE_LIBEDIT)
   list(APPEND LLDB_LIBEDIT_LIBS LibEdit::LibEdit)
 endif()
 
+add_subdirectory(Interfaces)
+
 add_lldb_library(lldbPluginScriptInterpreterPython PLUGIN
   PythonDataObjects.cpp
   PythonReadline.cpp
   ScriptInterpreterPython.cpp
-  ScriptedPythonInterface.cpp
-  ScriptedProcessPythonInterface.cpp
-  ScriptedThreadPythonInterface.cpp
-  ScriptedPlatformPythonInterface.cpp
 
   LINK_LIBS
     lldbBreakpoint
@@ -35,6 +33,7 @@ add_lldb_library(lldbPluginScriptInterpreterPython PLUGIN
     lldbHost
     lldbInterpreter
     lldbTarget
+    lldbPluginScriptInterpreterPythonInterfaces
     ${Python3_LIBRARIES}
     ${LLDB_LIBEDIT_LIBS}
 
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt
new file mode 100644
index 000000000000000..73aeb32ead855e8
--- /dev/null
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt
@@ -0,0 +1,38 @@
+if (APPLE AND LLVM_ENABLE_LOCAL_SUBMODULE_VISIBILITY)
+  # Work around an issue with the Python headers, which have a modular include
+  # inside an extern "C" block.
+  remove_module_flags()
+endif()
+
+if(NOT LLDB_PYTHON_RELATIVE_PATH)
+  message(FATAL_ERROR "LLDB_PYTHON_RELATIVE_PATH is not set.")
+endif()
+add_definitions(-DLLDB_PYTHON_RELATIVE_LIBDIR="${LLDB_PYTHON_RELATIVE_PATH}")
+
+if(NOT LLDB_PYTHON_EXE_RELATIVE_PATH)
+  message(FATAL_ERROR "LLDB_PYTHON_EXE_RELATIVE_PATH is not set.")
+endif()
+add_definitions(-DLLDB_PYTHON_EXE_RELATIVE_PATH="${LLDB_PYTHON_EXE_RELATIVE_PATH}")
+
+
+if (LLDB_ENABLE_LIBEDIT)
+  list(APPEND LLDB_LIBEDIT_LIBS LibEdit::LibEdit)
+endif()
+
+add_lldb_library(lldbPluginScriptInterpreterPythonInterfaces
+  ScriptedPythonInterface.cpp
+  ScriptedProcessPythonInterface.cpp
+  ScriptedThreadPythonInterface.cpp
+  ScriptedPlatformPythonInterface.cpp
+
+  LINK_LIBS
+    lldbCore
+    lldbHost
+    lldbInterpreter
+    lldbTarget
+    ${Python3_LIBRARIES}
+    ${LLDB_LIBEDIT_LIBS}
+
+  LINK_COMPONENTS
+    Support
+  )
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.cpp
similarity index 97%
rename from lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.cpp
rename to lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.cpp
index a0c55874c70a4a0..9bed33516915d08 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.cpp
@@ -14,10 +14,10 @@
 #if LLDB_ENABLE_PYTHON
 
 // LLDB Python header must be included first
-#include "lldb-python.h"
+#include "../lldb-python.h"
 
-#include "SWIGPythonBridge.h"
-#include "ScriptInterpreterPythonImpl.h"
+#include "../SWIGPythonBridge.h"
+#include "../ScriptInterpreterPythonImpl.h"
 #include "ScriptedPlatformPythonInterface.h"
 
 using namespace lldb;
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.h
similarity index 80%
rename from lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.h
rename to lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.h
index 1e3ad9962325a3f..02deecd15ede062 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.h
@@ -6,15 +6,15 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPLATFORMPYTHONINTERFACE_H
-#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPLATFORMPYTHONINTERFACE_H
+#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPLATFORMPYTHONINTERFACE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPLATFORMPYTHONINTERFACE_H
 
 #include "lldb/Host/Config.h"
 
 #if LLDB_ENABLE_PYTHON
 
 #include "ScriptedPythonInterface.h"
-#include "lldb/Interpreter/ScriptedPlatformInterface.h"
+#include "lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h"
 
 namespace lldb_private {
 class ScriptedPlatformPythonInterface : public ScriptedPlatformInterface,
@@ -41,4 +41,4 @@ class ScriptedPlatformPythonInterface : public ScriptedPlatformInterface,
 } // namespace lldb_private
 
 #endif // LLDB_ENABLE_PYTHON
-#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPLATFORMPYTHONINTERFACE_H
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPLATFORMPYTHONINTERFACE_H
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.cpp
similarity index 97%
rename from lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
rename to lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.cpp
index 019924fa19718f0..63a4db1ff5973e7 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.cpp
@@ -9,7 +9,7 @@
 #include "lldb/Host/Config.h"
 #if LLDB_ENABLE_PYTHON
 // LLDB Python header must be included first
-#include "lldb-python.h"
+#include "../lldb-python.h"
 #endif
 #include "lldb/Target/Process.h"
 #include "lldb/Utility/Log.h"
@@ -18,8 +18,8 @@
 
 #if LLDB_ENABLE_PYTHON
 
-#include "SWIGPythonBridge.h"
-#include "ScriptInterpreterPythonImpl.h"
+#include "../SWIGPythonBridge.h"
+#include "../ScriptInterpreterPythonImpl.h"
 #include "ScriptedProcessPythonInterface.h"
 #include "ScriptedThreadPythonInterface.h"
 #include <optional>
@@ -199,7 +199,7 @@ ScriptedProcessPythonInterface::GetScriptedThreadPluginName() {
 
 lldb::ScriptedThreadInterfaceSP
 ScriptedProcessPythonInterface::CreateScriptedThreadInterface() {
-  return std::make_shared<ScriptedThreadPythonInterface>(m_interpreter);
+  return m_interpreter.CreateScriptedThreadInterface();
 }
 
 StructuredData::DictionarySP ScriptedProcessPythonInterface::GetMetadata() {
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.h
similarity index 86%
rename from lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
rename to lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.h
index ff03eab07648a84..11330f5591b74e6 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.h
@@ -6,15 +6,15 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSPYTHONINTERFACE_H
-#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSPYTHONINTERFACE_H
+#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPROCESSPYTHONINTERFACE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPROCESSPYTHONINTERFACE_H
 
 #include "lldb/Host/Config.h"
 
 #if LLDB_ENABLE_PYTHON
 
 #include "ScriptedPythonInterface.h"
-#include "lldb/Interpreter/ScriptedProcessInterface.h"
+#include "lldb/Interpreter/Interfaces/ScriptedProcessInterface.h"
 #include <optional>
 
 namespace lldb_private {
@@ -68,4 +68,4 @@ class ScriptedProcessPythonInterface : public ScriptedProcessInterface,
 } // namespace lldb_private
 
 #endif // LLDB_ENABLE_PYTHON
-#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSPYTHONINTERFACE_H
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPROCESSPYTHONINTERFACE_H
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
similarity index 98%
rename from lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp
rename to lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
index 1e36a81fde54e8b..6f22503b279ca62 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
@@ -13,9 +13,9 @@
 #if LLDB_ENABLE_PYTHON
 
 // LLDB Python header must be included first
-#include "lldb-python.h"
+#include "../lldb-python.h"
 
-#include "ScriptInterpreterPythonImpl.h"
+#include "../ScriptInterpreterPythonImpl.h"
 #include "ScriptedPythonInterface.h"
 #include <optional>
 
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
similarity index 95%
rename from lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
rename to lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
index 4d0645d18acad4a..9163b8f6aede7d1 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPYTHONINTERFACE_H
-#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPYTHONINTERFACE_H
+#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPYTHONINTERFACE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPYTHONINTERFACE_H
 
 #if LLDB_ENABLE_PYTHON
 
@@ -18,12 +18,12 @@
 #include <utility>
 
 #include "lldb/Host/Config.h"
-#include "lldb/Interpreter/ScriptedInterface.h"
+#include "lldb/Interpreter/Interfaces/ScriptedInterface.h"
 #include "lldb/Utility/DataBufferHeap.h"
 
-#include "PythonDataObjects.h"
-#include "SWIGPythonBridge.h"
-#include "ScriptInterpreterPythonImpl.h"
+#include "../PythonDataObjects.h"
+#include "../SWIGPythonBridge.h"
+#include "../ScriptInterpreterPythonImpl.h"
 
 namespace lldb_private {
 class ScriptInterpreterPythonImpl;
@@ -146,7 +146,6 @@ class ScriptedPythonInterface : virtual public ScriptedInterface {
     original_arg = ExtractValueFromPythonObject<T>(transformed_arg, error);
   }
 
-
   void ReverseTransform(bool &original_arg,
                         python::PythonObject transformed_arg, Status &error) {
     python::PythonBoolean boolean_arg = python::PythonBoolean(
@@ -254,4 +253,4 @@ ScriptedPythonInterface::ExtractValueFromPythonObject<
 } // namespace lldb_private
 
 #endif // LLDB_ENABLE_PYTHON
-#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPYTHONINTERFACE_H
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPYTHONINTERFACE_H
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp
similarity index 97%
rename from lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
rename to lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp
index 5603a1541314a56..6addcd46e045efc 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp
@@ -13,10 +13,10 @@
 #if LLDB_ENABLE_PYTHON
 
 // LLDB Python header must be included first
-#include "lldb-python.h"
+#include "../lldb-python.h"
 
-#include "SWIGPythonBridge.h"
-#include "ScriptInterpreterPythonImpl.h"
+#include "../SWIGPythonBridge.h"
+#include "../ScriptInterpreterPythonImpl.h"
 #include "ScriptedThreadPythonInterface.h"
 #include <optional>
 
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.h
similarity index 81%
rename from lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h
rename to lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.h
index eac4941f88145dd..b63760fd5b5713d 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.h
@@ -6,15 +6,15 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDTHREADPYTHONINTERFACE_H
-#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDTHREADPYTHONINTERFACE_H
+#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDTHREADPYTHONINTERFACE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDTHREADPYTHONINTERFACE_H
 
 #include "lldb/Host/Config.h"
 
 #if LLDB_ENABLE_PYTHON
 
 #include "ScriptedPythonInterface.h"
-#include "lldb/Interpreter/ScriptedProcessInterface.h"
+#include "lldb/Interpreter/Interfaces/ScriptedThreadInterface.h"
 #include <optional>
 
 namespace lldb_private {
@@ -49,4 +49,4 @@ class ScriptedThreadPythonInterface : public ScriptedThreadInterface,
 } // namespace lldb_private
 
 #endif // LLDB_ENABLE_PYTHON
-#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDTHREADPYTHONINTERFACE_H
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDTHREADPYTHONINTERFACE_H
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 0d6ff6660acd3db..66e6ac796c9340b 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -14,12 +14,13 @@
 // LLDB Python header must be included first
 #include "lldb-python.h"
 
+#include "Interfaces/ScriptedPlatformPythonInterface.h"
+#include "Interfaces/ScriptedProcessPythonInterface.h"
+#include "Interfaces/ScriptedThreadPythonInterface.h"
 #include "PythonDataObjects.h"
 #include "PythonReadline.h"
 #include "SWIGPythonBridge.h"
 #include "ScriptInterpreterPythonImpl.h"
-#include "ScriptedPlatformPythonInterface.h"
-#include "ScriptedProcessPythonInterface.h"
 
 #include "lldb/API/SBError.h"
 #include "lldb/API/SBFrame.h"
@@ -1515,6 +1516,11 @@ ScriptInterpreterPythonImpl::CreateScriptedProcessInterface() {
   return std::make_unique<ScriptedProcessPythonInterface>(*this);
 }
 
+ScriptedThreadInterfaceSP
+ScriptInterpreterPythonImpl::CreateScriptedThreadInterface() {
+  return std::make_shared<ScriptedThreadPythonInterface>(*this);
+}
+
 StructuredData::ObjectSP
 ScriptInterpreterPythonImpl::CreateStructuredDataFromScriptObject(
     ScriptObject obj) {
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
index 01db6c5203007a1..00dc1d1baa309f6 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -140,6 +140,7 @@ class ScriptInterpreterPythonImpl : public ScriptInterpreterPython {
 
   StructuredData::DictionarySP
   OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
+  lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override;
 
   StructuredData::ArraySP
   OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override;

>From f305dded1ed6ff289b98f53899a6aa41ec9369ad Mon Sep 17 00:00:00 2001
From: Med Ismail Bennani <ismail at bennani.ma>
Date: Thu, 31 Aug 2023 22:37:35 +0100
Subject: [PATCH 2/6] [lldb] Move template python files to separate directory

This patch moves the template files for the various scripting
affordances to a separate directory.

This is a preparatory work for upcoming improvements and consolidations
to other scripting affordances.

Differential Revision: https://reviews.llvm.org/D159310

Signed-off-by: Med Ismail Bennani <ismail at bennani.ma>
---
 lldb/bindings/python/CMakeLists.txt                         | 6 +++---
 .../{scripted_process => }/crashlog_scripted_process.py     | 0
 .../{scripted_process => templates}/scripted_platform.py    | 0
 .../{scripted_process => templates}/scripted_process.py     | 0
 4 files changed, 3 insertions(+), 3 deletions(-)
 rename lldb/examples/python/{scripted_process => }/crashlog_scripted_process.py (100%)
 rename lldb/examples/python/{scripted_process => templates}/scripted_platform.py (100%)
 rename lldb/examples/python/{scripted_process => templates}/scripted_process.py (100%)

diff --git a/lldb/bindings/python/CMakeLists.txt b/lldb/bindings/python/CMakeLists.txt
index 2cc3ad1bb98b73e..c4806bda27049c6 100644
--- a/lldb/bindings/python/CMakeLists.txt
+++ b/lldb/bindings/python/CMakeLists.txt
@@ -103,15 +103,15 @@ function(finish_swig_python swig_target lldb_python_bindings_dir lldb_python_tar
     ${lldb_python_target_dir}
     "plugins"
     FILES
-    "${LLDB_SOURCE_DIR}/examples/python/scripted_process/scripted_process.py"
-    "${LLDB_SOURCE_DIR}/examples/python/scripted_process/scripted_platform.py")
+    "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_process.py"
+    "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_platform.py")
 
   if(APPLE)
     create_python_package(
       ${swig_target}
       ${lldb_python_target_dir} "macosx"
       FILES "${LLDB_SOURCE_DIR}/examples/python/crashlog.py"
-            "${LLDB_SOURCE_DIR}/examples/python/scripted_process/crashlog_scripted_process.py"
+            "${LLDB_SOURCE_DIR}/examples/python/crashlog_scripted_process.py"
             "${LLDB_SOURCE_DIR}/examples/darwin/heap_find/heap.py")
 
     create_python_package(
diff --git a/lldb/examples/python/scripted_process/crashlog_scripted_process.py b/lldb/examples/python/crashlog_scripted_process.py
similarity index 100%
rename from lldb/examples/python/scripted_process/crashlog_scripted_process.py
rename to lldb/examples/python/crashlog_scripted_process.py
diff --git a/lldb/examples/python/scripted_process/scripted_platform.py b/lldb/examples/python/templates/scripted_platform.py
similarity index 100%
rename from lldb/examples/python/scripted_process/scripted_platform.py
rename to lldb/examples/python/templates/scripted_platform.py
diff --git a/lldb/examples/python/scripted_process/scripted_process.py b/lldb/examples/python/templates/scripted_process.py
similarity index 100%
rename from lldb/examples/python/scripted_process/scripted_process.py
rename to lldb/examples/python/templates/scripted_process.py

>From 611fcf3b05750871d924e10b91aab74aa82a6980 Mon Sep 17 00:00:00 2001
From: Med Ismail Bennani <ismail at bennani.ma>
Date: Thu, 31 Aug 2023 23:05:18 +0100
Subject: [PATCH 3/6] [lldb] Introduce OperatingSystem{,Python}Interface and
 make us it

This patch aims to consolidate the OperatingSystem scripting affordance
by introducing a stable interface that conforms to the
Scripted{,Python}Interface.

This unify the way we call into python methods from lldb while
also improving its capabilities by allowing us to pass lldb_private
objects are arguments.

Differential Revision: https://reviews.llvm.org/D159314

Signed-off-by: Med Ismail Bennani <ismail at bennani.ma>
---
 lldb/bindings/python/python-wrapper.swig      |  17 +-
 lldb/bindings/python/python.swig              |   1 +
 .../Interfaces/OperatingSystemInterface.h     |  33 ++++
 .../lldb/Interpreter/ScriptInterpreter.h      |  11 +-
 lldb/include/lldb/lldb-forward.h              |   3 +
 .../Python/OperatingSystemPython.cpp          | 150 +++++++----------
 .../Python/OperatingSystemPython.h            |   7 +-
 .../Python/Interfaces/CMakeLists.txt          |   1 +
 .../OperatingSystemPythonInterface.cpp        |  77 +++++++++
 .../OperatingSystemPythonInterface.h          |  44 +++++
 .../Python/ScriptInterpreterPython.cpp        | 159 +-----------------
 .../Python/ScriptInterpreterPythonImpl.h      |  17 +-
 12 files changed, 251 insertions(+), 269 deletions(-)
 create mode 100644 lldb/include/lldb/Interpreter/Interfaces/OperatingSystemInterface.h
 create mode 100644 lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.cpp
 create mode 100644 lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.h

diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig
index cb54901e66d03c6..758fdf6c80c0029 100644
--- a/lldb/bindings/python/python-wrapper.swig
+++ b/lldb/bindings/python/python-wrapper.swig
@@ -263,11 +263,20 @@ PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateScriptedObjec
   }
 
   PythonObject result = {};
-  if (arg_info.get().max_positional_args == 2) {
+  switch (arg_info.get().max_positional_args) {
+    case 1:
+      // FIXME: Since this is used by different scripting affordances, they can have different number
+      // of argument but also different types of arguments (i.e SBExecutionContect vs SBProcess)
+      // We need to have a more reliable way to forward positional arguments.
+      result = pfunc(SWIGBridge::ToSWIGWrapper(exe_ctx_sp->GetProcessSP()));
+      break;
+    case 2:
       result = pfunc(SWIGBridge::ToSWIGWrapper(exe_ctx_sp), SWIGBridge::ToSWIGWrapper(args_impl));
-  } else {
-    error_string.assign("wrong number of arguments in __init__, should be 2 "
-                        "(not including self)");
+      break;
+    default:
+      error_string.assign("wrong number of arguments in __init__, should be 2 "
+                          "(not including self)");
+      break;
   }
   return result;
 }
diff --git a/lldb/bindings/python/python.swig b/lldb/bindings/python/python.swig
index 278c0eed2bab27f..a8ead02250d9cd0 100644
--- a/lldb/bindings/python/python.swig
+++ b/lldb/bindings/python/python.swig
@@ -116,6 +116,7 @@ def lldb_iter(obj, getsize, getelem):
 %{
 #include "../source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h"
 #include "../source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h"
+#include "../include/lldb/Target/ExecutionContext.h"
 #include "../bindings/python/python-swigsafecast.swig"
 using namespace lldb_private;
 using namespace lldb_private::python;
diff --git a/lldb/include/lldb/Interpreter/Interfaces/OperatingSystemInterface.h b/lldb/include/lldb/Interpreter/Interfaces/OperatingSystemInterface.h
new file mode 100644
index 000000000000000..3c46f99f3b356fe
--- /dev/null
+++ b/lldb/include/lldb/Interpreter/Interfaces/OperatingSystemInterface.h
@@ -0,0 +1,33 @@
+//===-- OperatingSystemInterface.h ------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_INTERPRETER_INTERFACES_OPERATINGSYSTEMINTERFACE_H
+#define LLDB_INTERPRETER_INTERFACES_OPERATINGSYSTEMINTERFACE_H
+
+#include "ScriptedThreadInterface.h"
+#include "lldb/Core/StructuredDataImpl.h"
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+class OperatingSystemInterface : virtual public ScriptedThreadInterface {
+public:
+  virtual StructuredData::DictionarySP CreateThread(lldb::tid_t tid,
+                                                    lldb::addr_t context) {
+    return {};
+  }
+
+  virtual StructuredData::ArraySP GetThreadInfo() { return {}; }
+
+  virtual std::optional<std::string> GetRegisterContextForTID(lldb::tid_t tid) {
+    return std::nullopt;
+  }
+};
+} // namespace lldb_private
+
+#endif // LLDB_INTERPRETER_INTERFACES_OPERATINGSYSTEMINTERFACE_H
diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
index eacd10d5279be6f..57a1962441e9510 100644
--- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -21,6 +21,7 @@
 #include "lldb/Core/ThreadedCommunication.h"
 #include "lldb/Host/PseudoTerminal.h"
 #include "lldb/Host/StreamFile.h"
+#include "lldb/Interpreter/Interfaces/OperatingSystemInterface.h"
 #include "lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h"
 #include "lldb/Interpreter/Interfaces/ScriptedProcessInterface.h"
 #include "lldb/Interpreter/Interfaces/ScriptedThreadInterface.h"
@@ -252,12 +253,6 @@ class ScriptInterpreter : public PluginInterface {
     return lldb::ValueObjectListSP();
   }
 
-  virtual StructuredData::GenericSP
-  OSPlugin_CreatePluginObject(const char *class_name,
-                              lldb::ProcessSP process_sp) {
-    return StructuredData::GenericSP();
-  }
-
   virtual StructuredData::DictionarySP
   OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) {
     return StructuredData::DictionarySP();
@@ -593,6 +588,10 @@ class ScriptInterpreter : public PluginInterface {
     return std::make_shared<ScriptedThreadInterface>();
   }
 
+  virtual lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() {
+    return std::make_shared<OperatingSystemInterface>();
+  }
+
   ScriptedPlatformInterface &GetScriptedPlatformInterface() {
     return *m_scripted_platform_interface_up;
   }
diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index 3cd71c8a4ba3c0a..aa099d4abc3b09f 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -130,6 +130,7 @@ class ObjectContainer;
 class ObjectFile;
 class ObjectFileJITDelegate;
 class OperatingSystem;
+class OperatingSystemInterface;
 class OptionGroup;
 class OptionGroupOptions;
 class OptionGroupPlatform;
@@ -360,6 +361,8 @@ typedef std::shared_ptr<lldb_private::ObjectFileJITDelegate>
 typedef std::weak_ptr<lldb_private::ObjectFileJITDelegate>
     ObjectFileJITDelegateWP;
 typedef std::unique_ptr<lldb_private::OperatingSystem> OperatingSystemUP;
+typedef std::shared_ptr<lldb_private::OperatingSystemInterface>
+    OperatingSystemInterfaceSP;
 typedef std::shared_ptr<lldb_private::OptionValue> OptionValueSP;
 typedef std::weak_ptr<lldb_private::OptionValue> OptionValueWP;
 typedef std::shared_ptr<lldb_private::OptionValueProperties>
diff --git a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
index 9560ae108f3e354..9a5dd515489231c 100644
--- a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
+++ b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
@@ -74,47 +74,69 @@ llvm::StringRef OperatingSystemPython::GetPluginDescriptionStatic() {
 OperatingSystemPython::OperatingSystemPython(lldb_private::Process *process,
                                              const FileSpec &python_module_path)
     : OperatingSystem(process), m_thread_list_valobj_sp(), m_register_info_up(),
-      m_interpreter(nullptr), m_python_object_sp() {
+      m_interpreter(nullptr), m_script_object_sp() {
   if (!process)
     return;
   TargetSP target_sp = process->CalculateTarget();
   if (!target_sp)
     return;
   m_interpreter = target_sp->GetDebugger().GetScriptInterpreter();
-  if (m_interpreter) {
-
-    std::string os_plugin_class_name(
-        python_module_path.GetFilename().AsCString(""));
-    if (!os_plugin_class_name.empty()) {
-      LoadScriptOptions options;
-      char python_module_path_cstr[PATH_MAX];
-      python_module_path.GetPath(python_module_path_cstr,
-                                 sizeof(python_module_path_cstr));
-      Status error;
-      if (m_interpreter->LoadScriptingModule(python_module_path_cstr, options,
-                                             error)) {
-        // Strip the ".py" extension if there is one
-        size_t py_extension_pos = os_plugin_class_name.rfind(".py");
-        if (py_extension_pos != std::string::npos)
-          os_plugin_class_name.erase(py_extension_pos);
-        // Add ".OperatingSystemPlugIn" to the module name to get a string like
-        // "modulename.OperatingSystemPlugIn"
-        os_plugin_class_name += ".OperatingSystemPlugIn";
-        StructuredData::ObjectSP object_sp =
-            m_interpreter->OSPlugin_CreatePluginObject(
-                os_plugin_class_name.c_str(), process->CalculateProcess());
-        if (object_sp && object_sp->IsValid())
-          m_python_object_sp = object_sp;
-      }
-    }
-  }
+  if (!m_interpreter)
+    return;
+
+  std::string os_plugin_class_name(
+      python_module_path.GetFilename().AsCString(""));
+  if (os_plugin_class_name.empty())
+    return;
+
+  LoadScriptOptions options;
+  char python_module_path_cstr[PATH_MAX];
+  python_module_path.GetPath(python_module_path_cstr,
+                             sizeof(python_module_path_cstr));
+  Status error;
+  if (!m_interpreter->LoadScriptingModule(python_module_path_cstr, options,
+                                          error))
+    return;
+
+  // Strip the ".py" extension if there is one
+  size_t py_extension_pos = os_plugin_class_name.rfind(".py");
+  if (py_extension_pos != std::string::npos)
+    os_plugin_class_name.erase(py_extension_pos);
+  // Add ".OperatingSystemPlugIn" to the module name to get a string like
+  // "modulename.OperatingSystemPlugIn"
+  os_plugin_class_name += ".OperatingSystemPlugIn";
+
+  auto operating_system_interface =
+      m_interpreter->CreateOperatingSystemInterface();
+  if (!operating_system_interface)
+    //    return llvm::createStringError(
+    //        llvm::inconvertibleErrorCode(),
+    //        "Failed to create scripted thread interface.");
+    return;
+
+  ExecutionContext exe_ctx(process);
+  StructuredData::GenericSP owned_script_object_sp =
+      operating_system_interface->CreatePluginObject(os_plugin_class_name,
+                                                     exe_ctx, nullptr);
+
+  if (!owned_script_object_sp)
+    //    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+    //                                   "Failed to create script object.");
+    return;
+  if (!owned_script_object_sp->IsValid())
+    //    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+    //                                   "Created script object is invalid.");
+    return;
+
+  m_script_object_sp = owned_script_object_sp;
+  m_operating_system_interface_sp = operating_system_interface;
 }
 
 OperatingSystemPython::~OperatingSystemPython() = default;
 
 DynamicRegisterInfo *OperatingSystemPython::GetDynamicRegisterInfo() {
   if (m_register_info_up == nullptr) {
-    if (!m_interpreter || !m_python_object_sp)
+    if (!m_interpreter || !m_operating_system_interface_sp)
       return nullptr;
     Log *log = GetLog(LLDBLog::OS);
 
@@ -124,7 +146,7 @@ DynamicRegisterInfo *OperatingSystemPython::GetDynamicRegisterInfo() {
               m_process->GetID());
 
     StructuredData::DictionarySP dictionary =
-        m_interpreter->OSPlugin_RegisterInfo(m_python_object_sp);
+        m_operating_system_interface_sp->GetRegisterInfo();
     if (!dictionary)
       return nullptr;
 
@@ -140,27 +162,11 @@ DynamicRegisterInfo *OperatingSystemPython::GetDynamicRegisterInfo() {
 bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list,
                                              ThreadList &core_thread_list,
                                              ThreadList &new_thread_list) {
-  if (!m_interpreter || !m_python_object_sp)
+  if (!m_interpreter || !m_operating_system_interface_sp)
     return false;
 
   Log *log = GetLog(LLDBLog::OS);
 
-  // First thing we have to do is to try to get the API lock, and the
-  // interpreter lock. We're going to change the thread content of the process,
-  // and we're going to use python, which requires the API lock to do it. We
-  // need the interpreter lock to make sure thread_info_dict stays alive.
-  //
-  // If someone already has the API lock, that is ok, we just want to avoid
-  // external code from making new API calls while this call is happening.
-  //
-  // This is a recursive lock so we can grant it to any Python code called on
-  // the stack below us.
-  Target &target = m_process->GetTarget();
-  std::unique_lock<std::recursive_mutex> api_lock(target.GetAPIMutex(),
-                                                  std::defer_lock);
-  (void)api_lock.try_lock(); // See above.
-  auto interpreter_lock = m_interpreter->AcquireInterpreterLock();
-
   LLDB_LOGF(log,
             "OperatingSystemPython::UpdateThreadList() fetching thread "
             "data from python for pid %" PRIu64,
@@ -170,7 +176,7 @@ bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list,
   // the lldb_private::Process subclass, no memory threads will be in this
   // list.
   StructuredData::ArraySP threads_list =
-      m_interpreter->OSPlugin_ThreadsInfo(m_python_object_sp);
+      m_operating_system_interface_sp->GetThreadInfo();
 
   const uint32_t num_cores = core_thread_list.GetSize(false);
 
@@ -281,28 +287,12 @@ RegisterContextSP
 OperatingSystemPython::CreateRegisterContextForThread(Thread *thread,
                                                       addr_t reg_data_addr) {
   RegisterContextSP reg_ctx_sp;
-  if (!m_interpreter || !m_python_object_sp || !thread)
+  if (!m_interpreter || !m_script_object_sp || !thread)
     return reg_ctx_sp;
 
   if (!IsOperatingSystemPluginThread(thread->shared_from_this()))
     return reg_ctx_sp;
 
-  // First thing we have to do is to try to get the API lock, and the
-  // interpreter lock. We're going to change the thread content of the process,
-  // and we're going to use python, which requires the API lock to do it. We
-  // need the interpreter lock to make sure thread_info_dict stays alive.
-  //
-  // If someone already has the API lock, that is ok, we just want to avoid
-  // external code from making new API calls while this call is happening.
-  //
-  // This is a recursive lock so we can grant it to any Python code called on
-  // the stack below us.
-  Target &target = m_process->GetTarget();
-  std::unique_lock<std::recursive_mutex> api_lock(target.GetAPIMutex(),
-                                                  std::defer_lock);
-  (void)api_lock.try_lock(); // See above.
-  auto interpreter_lock = m_interpreter->AcquireInterpreterLock();
-
   Log *log = GetLog(LLDBLog::Thread);
 
   if (reg_data_addr != LLDB_INVALID_ADDRESS) {
@@ -324,11 +314,11 @@ OperatingSystemPython::CreateRegisterContextForThread(Thread *thread,
               ") fetching register data from python",
               thread->GetID(), thread->GetProtocolID());
 
-    StructuredData::StringSP reg_context_data =
-        m_interpreter->OSPlugin_RegisterContextData(m_python_object_sp,
-                                                    thread->GetID());
+    std::optional<std::string> reg_context_data =
+        m_operating_system_interface_sp->GetRegisterContextForTID(
+            thread->GetID());
     if (reg_context_data) {
-      std::string value = std::string(reg_context_data->GetValue());
+      std::string value = *reg_context_data;
       DataBufferSP data_sp(new DataBufferHeap(value.c_str(), value.length()));
       if (data_sp->GetByteSize()) {
         RegisterContextMemory *reg_ctx_memory = new RegisterContextMemory(
@@ -347,6 +337,7 @@ OperatingSystemPython::CreateRegisterContextForThread(Thread *thread,
               "OperatingSystemPython::CreateRegisterContextForThread (tid "
               "= 0x%" PRIx64 ") forcing a dummy register context",
               thread->GetID());
+    Target &target = m_process->GetTarget();
     reg_ctx_sp = std::make_shared<RegisterContextDummy>(
         *thread, 0, target.GetArchitecture().GetAddressByteSize());
   }
@@ -372,26 +363,11 @@ lldb::ThreadSP OperatingSystemPython::CreateThread(lldb::tid_t tid,
             ", context = 0x%" PRIx64 ") fetching register data from python",
             tid, context);
 
-  if (m_interpreter && m_python_object_sp) {
-    // First thing we have to do is to try to get the API lock, and the
-    // interpreter lock. We're going to change the thread content of the
-    // process, and we're going to use python, which requires the API lock to
-    // do it. We need the interpreter lock to make sure thread_info_dict stays
-    // alive.
-    //
-    // If someone already has the API lock, that is ok, we just want to avoid
-    // external code from making new API calls while this call is happening.
-    //
-    // This is a recursive lock so we can grant it to any Python code called on
-    // the stack below us.
-    Target &target = m_process->GetTarget();
-    std::unique_lock<std::recursive_mutex> api_lock(target.GetAPIMutex(),
-                                                    std::defer_lock);
-    (void)api_lock.try_lock(); // See above.
-    auto interpreter_lock = m_interpreter->AcquireInterpreterLock();
+  if (m_interpreter && m_script_object_sp) {
 
     StructuredData::DictionarySP thread_info_dict =
-        m_interpreter->OSPlugin_CreateThread(m_python_object_sp, tid, context);
+        m_operating_system_interface_sp->CreateThread(tid, context);
+
     std::vector<bool> core_used_map;
     if (thread_info_dict) {
       ThreadList core_threads(m_process);
diff --git a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
index 7800cf03af8e888..90973acde3ebfd0 100644
--- a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
+++ b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
@@ -62,7 +62,7 @@ class OperatingSystemPython : public lldb_private::OperatingSystem {
 
 protected:
   bool IsValid() const {
-    return m_python_object_sp && m_python_object_sp->IsValid();
+    return m_script_object_sp && m_script_object_sp->IsValid();
   }
 
   lldb::ThreadSP CreateThreadFromThreadInfo(
@@ -75,8 +75,9 @@ class OperatingSystemPython : public lldb_private::OperatingSystem {
 
   lldb::ValueObjectSP m_thread_list_valobj_sp;
   std::unique_ptr<lldb_private::DynamicRegisterInfo> m_register_info_up;
-  lldb_private::ScriptInterpreter *m_interpreter;
-  lldb_private::StructuredData::ObjectSP m_python_object_sp;
+  lldb_private::ScriptInterpreter *m_interpreter = nullptr;
+  lldb::OperatingSystemInterfaceSP m_operating_system_interface_sp = nullptr;
+  lldb_private::StructuredData::GenericSP m_script_object_sp = nullptr;
 };
 
 #endif // LLDB_ENABLE_PYTHON
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt
index 73aeb32ead855e8..b22abc49c92a9a9 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt
@@ -20,6 +20,7 @@ if (LLDB_ENABLE_LIBEDIT)
 endif()
 
 add_lldb_library(lldbPluginScriptInterpreterPythonInterfaces
+  OperatingSystemPythonInterface.cpp
   ScriptedPythonInterface.cpp
   ScriptedProcessPythonInterface.cpp
   ScriptedThreadPythonInterface.cpp
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.cpp
new file mode 100644
index 000000000000000..45804d5d019d79d
--- /dev/null
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.cpp
@@ -0,0 +1,77 @@
+//===-- ScriptedThreadPythonInterface.cpp ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/Config.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/lldb-enumerations.h"
+
+#if LLDB_ENABLE_PYTHON
+
+// LLDB Python header must be included first
+#include "../lldb-python.h"
+
+#include "../SWIGPythonBridge.h"
+#include "../ScriptInterpreterPythonImpl.h"
+#include "OperatingSystemPythonInterface.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::python;
+using Locker = ScriptInterpreterPythonImpl::Locker;
+
+OperatingSystemPythonInterface::OperatingSystemPythonInterface(
+    ScriptInterpreterPythonImpl &interpreter)
+    : OperatingSystemInterface(), ScriptedThreadPythonInterface(interpreter) {}
+
+StructuredData::GenericSP OperatingSystemPythonInterface::CreatePluginObject(
+    llvm::StringRef class_name, ExecutionContext &exe_ctx,
+    StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
+  return ScriptedThreadPythonInterface::CreatePluginObject(class_name, exe_ctx,
+                                                           args_sp, script_obj);
+}
+
+StructuredData::DictionarySP
+OperatingSystemPythonInterface::CreateThread(lldb::tid_t tid,
+                                             lldb::addr_t context) {
+  Status error;
+  StructuredData::DictionarySP dict = Dispatch<StructuredData::DictionarySP>(
+      "create_thread", error, tid, context);
+
+  if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
+    return {};
+
+  return dict;
+}
+
+StructuredData::ArraySP OperatingSystemPythonInterface::GetThreadInfo() {
+  Status error;
+  StructuredData::ArraySP arr =
+      Dispatch<StructuredData::ArraySP>("get_thread_info", error);
+
+  if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr, error))
+    return {};
+
+  return arr;
+}
+
+StructuredData::DictionarySP OperatingSystemPythonInterface::GetRegisterInfo() {
+  return ScriptedThreadPythonInterface::GetRegisterInfo();
+}
+
+std::optional<std::string>
+OperatingSystemPythonInterface::GetRegisterContextForTID(lldb::tid_t tid) {
+  Status error;
+  StructuredData::ObjectSP obj = Dispatch("get_register_data", error, tid);
+
+  if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
+    return {};
+
+  return obj->GetAsString()->GetValue().str();
+}
+
+#endif
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.h
new file mode 100644
index 000000000000000..a69557ad7c43469
--- /dev/null
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.h
@@ -0,0 +1,44 @@
+//===-- OperatingSystemPythonInterface.h ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_OPERATINGSYSTEMPYTHONINTERFACE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_OPERATINGSYSTEMPYTHONINTERFACE_H
+
+#include "lldb/Host/Config.h"
+
+#if LLDB_ENABLE_PYTHON
+
+#include "ScriptedThreadPythonInterface.h"
+#include "lldb/Interpreter/Interfaces/OperatingSystemInterface.h"
+#include <optional>
+
+namespace lldb_private {
+class OperatingSystemPythonInterface
+    : virtual public OperatingSystemInterface,
+      virtual public ScriptedThreadPythonInterface {
+public:
+  OperatingSystemPythonInterface(ScriptInterpreterPythonImpl &interpreter);
+
+  StructuredData::GenericSP
+  CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx,
+                     StructuredData::DictionarySP args_sp,
+                     StructuredData::Generic *script_obj = nullptr) override;
+
+  StructuredData::DictionarySP CreateThread(lldb::tid_t tid,
+                                            lldb::addr_t context) override;
+
+  StructuredData::ArraySP GetThreadInfo() override;
+
+  StructuredData::DictionarySP GetRegisterInfo() override;
+
+  std::optional<std::string> GetRegisterContextForTID(lldb::tid_t tid) override;
+};
+} // namespace lldb_private
+
+#endif // LLDB_ENABLE_PYTHON
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_OPERATINGSYSTEMPYTHONINTERFACE_H
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 66e6ac796c9340b..a57c8e4984ad8a8 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -14,6 +14,7 @@
 // LLDB Python header must be included first
 #include "lldb-python.h"
 
+#include "Interfaces/OperatingSystemPythonInterface.h"
 #include "Interfaces/ScriptedPlatformPythonInterface.h"
 #include "Interfaces/ScriptedProcessPythonInterface.h"
 #include "Interfaces/ScriptedThreadPythonInterface.h"
@@ -1521,6 +1522,11 @@ ScriptInterpreterPythonImpl::CreateScriptedThreadInterface() {
   return std::make_shared<ScriptedThreadPythonInterface>(*this);
 }
 
+OperatingSystemInterfaceSP
+ScriptInterpreterPythonImpl::CreateOperatingSystemInterface() {
+  return std::make_shared<OperatingSystemPythonInterface>(*this);
+}
+
 StructuredData::ObjectSP
 ScriptInterpreterPythonImpl::CreateStructuredDataFromScriptObject(
     ScriptObject obj) {
@@ -1532,159 +1538,6 @@ ScriptInterpreterPythonImpl::CreateStructuredDataFromScriptObject(
   return py_obj.CreateStructuredObject();
 }
 
-StructuredData::GenericSP
-ScriptInterpreterPythonImpl::OSPlugin_CreatePluginObject(
-    const char *class_name, lldb::ProcessSP process_sp) {
-  if (class_name == nullptr || class_name[0] == '\0')
-    return StructuredData::GenericSP();
-
-  if (!process_sp)
-    return StructuredData::GenericSP();
-
-  Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
-  PythonObject ret_val = SWIGBridge::LLDBSWIGPythonCreateOSPlugin(
-      class_name, m_dictionary_name.c_str(), process_sp);
-
-  return StructuredData::GenericSP(
-      new StructuredPythonObject(std::move(ret_val)));
-}
-
-StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_RegisterInfo(
-    StructuredData::ObjectSP os_plugin_object_sp) {
-  Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
-
-  if (!os_plugin_object_sp)
-    return {};
-
-  StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
-  if (!generic)
-    return {};
-
-  PythonObject implementor(PyRefType::Borrowed,
-                           (PyObject *)generic->GetValue());
-
-  if (!implementor.IsAllocated())
-    return {};
-
-  llvm::Expected<PythonObject> expected_py_return =
-      implementor.CallMethod("get_register_info");
-
-  if (!expected_py_return) {
-    llvm::consumeError(expected_py_return.takeError());
-    return {};
-  }
-
-  PythonObject py_return = std::move(expected_py_return.get());
-
-  if (py_return.get()) {
-    PythonDictionary result_dict(PyRefType::Borrowed, py_return.get());
-    return result_dict.CreateStructuredDictionary();
-  }
-  return StructuredData::DictionarySP();
-}
-
-StructuredData::ArraySP ScriptInterpreterPythonImpl::OSPlugin_ThreadsInfo(
-    StructuredData::ObjectSP os_plugin_object_sp) {
-  Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
-  if (!os_plugin_object_sp)
-    return {};
-
-  StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
-  if (!generic)
-    return {};
-
-  PythonObject implementor(PyRefType::Borrowed,
-                           (PyObject *)generic->GetValue());
-
-  if (!implementor.IsAllocated())
-    return {};
-
-  llvm::Expected<PythonObject> expected_py_return =
-      implementor.CallMethod("get_thread_info");
-
-  if (!expected_py_return) {
-    llvm::consumeError(expected_py_return.takeError());
-    return {};
-  }
-
-  PythonObject py_return = std::move(expected_py_return.get());
-
-  if (py_return.get()) {
-    PythonList result_list(PyRefType::Borrowed, py_return.get());
-    return result_list.CreateStructuredArray();
-  }
-  return StructuredData::ArraySP();
-}
-
-StructuredData::StringSP
-ScriptInterpreterPythonImpl::OSPlugin_RegisterContextData(
-    StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid) {
-  Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
-
-  if (!os_plugin_object_sp)
-    return {};
-
-  StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
-  if (!generic)
-    return {};
-  PythonObject implementor(PyRefType::Borrowed,
-                           (PyObject *)generic->GetValue());
-
-  if (!implementor.IsAllocated())
-    return {};
-
-  llvm::Expected<PythonObject> expected_py_return =
-      implementor.CallMethod("get_register_data", tid);
-
-  if (!expected_py_return) {
-    llvm::consumeError(expected_py_return.takeError());
-    return {};
-  }
-
-  PythonObject py_return = std::move(expected_py_return.get());
-
-  if (py_return.get()) {
-    PythonBytes result(PyRefType::Borrowed, py_return.get());
-    return result.CreateStructuredString();
-  }
-  return {};
-}
-
-StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_CreateThread(
-    StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid,
-    lldb::addr_t context) {
-  Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
-
-  if (!os_plugin_object_sp)
-    return {};
-
-  StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
-  if (!generic)
-    return {};
-
-  PythonObject implementor(PyRefType::Borrowed,
-                           (PyObject *)generic->GetValue());
-
-  if (!implementor.IsAllocated())
-    return {};
-
-  llvm::Expected<PythonObject> expected_py_return =
-      implementor.CallMethod("create_thread", tid, context);
-
-  if (!expected_py_return) {
-    llvm::consumeError(expected_py_return.takeError());
-    return {};
-  }
-
-  PythonObject py_return = std::move(expected_py_return.get());
-
-  if (py_return.get()) {
-    PythonDictionary result_dict(PyRefType::Borrowed, py_return.get());
-    return result_dict.CreateStructuredDictionary();
-  }
-  return StructuredData::DictionarySP();
-}
-
 StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan(
     const char *class_name, const StructuredDataImpl &args_data,
     std::string &error_str, lldb::ThreadPlanSP thread_plan_sp) {
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
index 00dc1d1baa309f6..a33499816d8d38c 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -134,24 +134,9 @@ class ScriptInterpreterPythonImpl : public ScriptInterpreterPython {
 
   lldb::ScriptedProcessInterfaceUP CreateScriptedProcessInterface() override;
 
-  StructuredData::GenericSP
-  OSPlugin_CreatePluginObject(const char *class_name,
-                              lldb::ProcessSP process_sp) override;
-
-  StructuredData::DictionarySP
-  OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
   lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override;
 
-  StructuredData::ArraySP
-  OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
-
-  StructuredData::StringSP
-  OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp,
-                               lldb::tid_t thread_id) override;
-
-  StructuredData::DictionarySP
-  OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp,
-                        lldb::tid_t tid, lldb::addr_t context) override;
+  lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() override;
 
   StructuredData::ObjectSP
   LoadPluginModule(const FileSpec &file_spec,

>From 9c459d5e7e5b22c30fdff221c97e803c7f9f2639 Mon Sep 17 00:00:00 2001
From: Med Ismail Bennani <ismail at bennani.ma>
Date: Fri, 1 Sep 2023 16:49:01 +0100
Subject: [PATCH 4/6] [lldb] Add OperatingSystem base class to the lldb python
 module

This patch introduces an `OperatingSystem` base implementation in the
`lldb` python module to make it easier for lldb users to write their own
implementation.

The `OperatingSystem` base implementation is derived itself from the
`ScriptedThread` base implementation since they share some common grounds.

To achieve that, this patch makes changes to the `ScriptedThread`
initializer since it gets called by the `OperatingSystem` initializer.

I also took the opportunity to document the `OperatingSystem` base
class and methods.

Differential Revision: https://reviews.llvm.org/D159315

Signed-off-by: Med Ismail Bennani <ismail at bennani.ma>
---
 lldb/bindings/python/CMakeLists.txt           |   3 +-
 .../python/templates/operating_system.py      | 103 ++++++++++++++++++
 .../python/templates/scripted_process.py      |  26 +++--
 .../python_os_plugin/operating_system.py      |  40 +------
 4 files changed, 124 insertions(+), 48 deletions(-)
 create mode 100644 lldb/examples/python/templates/operating_system.py

diff --git a/lldb/bindings/python/CMakeLists.txt b/lldb/bindings/python/CMakeLists.txt
index c4806bda27049c6..c941f764dfc92ac 100644
--- a/lldb/bindings/python/CMakeLists.txt
+++ b/lldb/bindings/python/CMakeLists.txt
@@ -104,7 +104,8 @@ function(finish_swig_python swig_target lldb_python_bindings_dir lldb_python_tar
     "plugins"
     FILES
     "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_process.py"
-    "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_platform.py")
+    "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_platform.py"
+    "${LLDB_SOURCE_DIR}/examples/python/templates/operating_system.py")
 
   if(APPLE)
     create_python_package(
diff --git a/lldb/examples/python/templates/operating_system.py b/lldb/examples/python/templates/operating_system.py
new file mode 100644
index 000000000000000..a8053bcaa21afe7
--- /dev/null
+++ b/lldb/examples/python/templates/operating_system.py
@@ -0,0 +1,103 @@
+from abc import abstractmethod
+
+import lldb
+import struct
+
+from lldb.plugins.scripted_process import ScriptedThread
+
+
+class OperatingSystem(ScriptedThread):
+    """
+    Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class.
+
+    ```
+    thread_info = {
+        "tid": tid,
+        "name": "four",
+        "queue": "queue4",
+        "state": "stopped",
+        "stop_reason": "none",
+        "core" : 2
+    }
+    ```
+
+    - tid : thread ID (mandatory)
+    - name : thread name (optional key/value pair)
+    - queue : thread dispatch queue name (optional key/value pair)
+    - state : thread state (mandatory, set to 'stopped' for now)
+    - core : the index of the core (lldb) thread that this OS Thread should shadow
+    - stop_reason : thread stop reason. (mandatory, usually set to 'none')
+        Possible values include:
+        - 'breakpoint': thread is stopped at a breakpoint
+        - 'none': thread is stopped because the process is stopped
+        - 'trace': thread is stopped after single stepping
+        The usual value for this while threads are in memory is 'none'
+    - register_data_addr : the address of the register data in memory (optional key/value pair)
+        Specifying this key/value pair for a thread will avoid a call to get_register_data()
+        and can be used when your registers are in a thread context structure that is contiguous
+        in memory. Don't specify this if your register layout in memory doesn't match the layout
+        described by the dictionary returned from a call to the get_register_info() method.
+    """
+
+    def __init__(self, process):
+        """Initialization needs a valid lldb.SBProcess object. This plug-in
+        will get created after a live process is valid and has stopped for the
+        first time.
+
+        Args:
+            process (lldb.SBProcess): The process owning this thread.
+        """
+        self.registers = None
+        super().__init__(process, None)
+        self.registers = self.register_info
+        self.threads = []
+
+    def create_thread(self, tid, context):
+        """Lazily create an operating system thread using a thread information
+        dictionary and an optional operating system thread context address.
+        This method is called manually, using the SBAPI
+        `lldb.SBProcess.CreateOSPluginThread` affordance.
+
+        Args:
+            tid (int): Thread ID to get `thread_info` dictionary for.
+            context (int): Address of the operating system thread struct.
+
+        Returns:
+            Dict: The `thread_info` dictionary containing the various information
+            for lldb to create a Thread object and add it to the process thread list.
+        """
+        return None
+
+    @abstractmethod
+    def get_thread_info(self):
+        """Get the list of operating system threads. This method gets called
+        automatically every time the process stops and it needs to update its
+        thread list.
+
+        Returns:
+            List[thread_info]: A list of `os_thread` dictionaries
+                containing at least for each entry, the thread id, it's name,
+                queue, state, stop reason. It can also contain a
+                `register_data_addr`. The list can be empty.
+        """
+        pass
+
+    @abstractmethod
+    def get_register_data(self, tid):
+        """Get the operating system thread register context for given a thread
+        id. This method is called when unwinding the stack of one of the
+        operating system threads.
+
+        Args:
+            tid (int): Thread ID to get register context for.
+
+        Returns:
+            str: A byte representing all register's value.
+        """
+        pass
+
+    def get_register_context(self):
+        pass
+
+    def get_stop_reason(self):
+        pass
diff --git a/lldb/examples/python/templates/scripted_process.py b/lldb/examples/python/templates/scripted_process.py
index d74ef02dec8591c..3ddcebd128eaa6e 100644
--- a/lldb/examples/python/templates/scripted_process.py
+++ b/lldb/examples/python/templates/scripted_process.py
@@ -244,16 +244,16 @@ class ScriptedThread(metaclass=ABCMeta):
     """
 
     @abstractmethod
-    def __init__(self, scripted_process, args):
+    def __init__(self, process, args):
         """Construct a scripted thread.
 
         Args:
-            process (ScriptedProcess): The scripted process owning this thread.
+            process (ScriptedProcess/lldb.SBProcess): The process owning this thread.
             args (lldb.SBStructuredData): A Dictionary holding arbitrary
                 key/value pairs used by the scripted thread.
         """
         self.target = None
-        self.scripted_process = None
+        self.originating_process = None
         self.process = None
         self.args = None
         self.idx = 0
@@ -268,9 +268,13 @@ def __init__(self, scripted_process, args):
         self.frames = []
         self.extended_info = []
 
-        if isinstance(scripted_process, ScriptedProcess):
-            self.target = scripted_process.target
-            self.scripted_process = scripted_process
+        if (
+            isinstance(process, ScriptedProcess)
+            or isinstance(process, lldb.SBProcess)
+            and process.IsValid()
+        ):
+            self.target = process.target
+            self.originating_process = process
             self.process = self.target.GetProcess()
             self.get_register_info()
 
@@ -354,14 +358,14 @@ def get_stackframes(self):
     def get_register_info(self):
         if self.register_info is None:
             self.register_info = dict()
-            if self.scripted_process.arch == "x86_64":
+            if self.originating_process.arch == "x86_64":
                 self.register_info["sets"] = ["General Purpose Registers"]
                 self.register_info["registers"] = INTEL64_GPR
-            elif "arm64" in self.scripted_process.arch:
+            elif "arm64" in self.originating_process.arch:
                 self.register_info["sets"] = ["General Purpose Registers"]
                 self.register_info["registers"] = ARM64_GPR
             else:
-                raise ValueError("Unknown architecture", self.scripted_process.arch)
+                raise ValueError("Unknown architecture", self.originating_process.arch)
         return self.register_info
 
     @abstractmethod
@@ -505,12 +509,12 @@ def get_stop_reason(self):
 
             # TODO: Passthrough stop reason from driving process
             if self.driving_thread.GetStopReason() != lldb.eStopReasonNone:
-                if "arm64" in self.scripted_process.arch:
+                if "arm64" in self.originating_process.arch:
                     stop_reason["type"] = lldb.eStopReasonException
                     stop_reason["data"][
                         "desc"
                     ] = self.driving_thread.GetStopDescription(100)
-                elif self.scripted_process.arch == "x86_64":
+                elif self.originating_process.arch == "x86_64":
                     stop_reason["type"] = lldb.eStopReasonSignal
                     stop_reason["data"]["signal"] = signal.SIGTRAP
                 else:
diff --git a/lldb/test/API/functionalities/plugins/python_os_plugin/operating_system.py b/lldb/test/API/functionalities/plugins/python_os_plugin/operating_system.py
index 52c678fac2efedf..f4404d78492f98d 100644
--- a/lldb/test/API/functionalities/plugins/python_os_plugin/operating_system.py
+++ b/lldb/test/API/functionalities/plugins/python_os_plugin/operating_system.py
@@ -1,29 +1,14 @@
-#!/usr/bin/env python
-
 import lldb
 import struct
 
+from lldb.plugins.operating_system import OperatingSystem
+
 
-class OperatingSystemPlugIn(object):
+class OperatingSystemPlugIn(OperatingSystem):
     """Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class"""
 
     def __init__(self, process):
-        """Initialization needs a valid.SBProcess object.
-
-        This plug-in will get created after a live process is valid and has stopped for the
-        first time."""
-        self.process = None
-        self.registers = None
-        self.threads = None
-        if isinstance(process, lldb.SBProcess) and process.IsValid():
-            self.process = process
-            self.threads = None  # Will be an dictionary containing info for each thread
-
-    def get_target(self):
-        # NOTE: Don't use "lldb.target" when trying to get your target as the "lldb.target"
-        # tracks the current target in the LLDB command interpreter which isn't the
-        # correct thing to use for this plug-in.
-        return self.process.target
+        super().__init__(process)
 
     def create_thread(self, tid, context):
         if tid == 0x444444444:
@@ -40,23 +25,6 @@ def create_thread(self, tid, context):
 
     def get_thread_info(self):
         if not self.threads:
-            # The sample dictionary below shows the values that can be returned for a thread
-            # tid => thread ID (mandatory)
-            # name => thread name (optional key/value pair)
-            # queue => thread dispatch queue name (optional key/value pair)
-            # state => thred state (mandatory, set to 'stopped' for now)
-            # stop_reason => thread stop reason. (mandatory, usually set to 'none')
-            #  Possible values include:
-            #   'breakpoint' if the thread is stopped at a breakpoint
-            #   'none' thread is just stopped because the process is stopped
-            #   'trace' the thread just single stepped
-            #   The usual value for this while threads are in memory is 'none'
-            # register_data_addr => the address of the register data in memory (optional key/value pair)
-            #   Specifying this key/value pair for a thread will avoid a call to get_register_data()
-            #   and can be used when your registers are in a thread context structure that is contiguous
-            #   in memory. Don't specify this if your register layout in memory doesn't match the layout
-            # described by the dictionary returned from a call to the
-            # get_register_info() method.
             self.threads = [
                 {
                     "tid": 0x111111111,

>From 0211a15706955d84776d68d2ccf7e2b0bb4c007e Mon Sep 17 00:00:00 2001
From: Med Ismail Bennani <ismail at bennani.ma>
Date: Sat, 26 Aug 2023 00:44:38 +0100
Subject: [PATCH 5/6] [lldb/docs] Add OperatingSystem documentation to the
 website

Signed-off-by: Med Ismail Bennani <ismail at bennani.ma>
---
 lldb/docs/use/python.rst | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/lldb/docs/use/python.rst b/lldb/docs/use/python.rst
index 6183d6935d80ef8..83e10b9df619bf6 100644
--- a/lldb/docs/use/python.rst
+++ b/lldb/docs/use/python.rst
@@ -11,6 +11,15 @@ some of these things by going through an example, explaining how to use
 Python scripting to find a bug in a program that searches for text in a
 large binary tree.
 
+Operating System Thread Plugins
+-------------------------------
+
+.. literalinclude:: ../../examples/python/templates/operating_system.py
+   :language: python
+   :linenos:
+   :encoding: utf-8
+   :pyobject: OperatingSystem
+
 The Test Program and Input
 --------------------------
 

>From 3ef039a731e09ec3767e71714fc273084c5773a8 Mon Sep 17 00:00:00 2001
From: Med Ismail Bennani <ismail at bennani.ma>
Date: Mon, 25 Sep 2023 20:46:46 +0200
Subject: [PATCH 6/6] [lldb] Add new interface for ScriptedThreadPlan

Signed-off-by: Med Ismail Bennani <ismail at bennani.ma>
---
 .../Interfaces/ScriptedInterface.h            | 10 ++-
 .../Interfaces/ScriptedPlatformInterface.h    |  8 +-
 .../Interfaces/ScriptedProcessInterface.h     |  8 +-
 .../Interfaces/ScriptedThreadInterface.h      |  8 +-
 .../Interfaces/ScriptedThreadPlanInterface.h  | 42 +++++++++
 .../lldb/Interpreter/ScriptInterpreter.h      | 41 ++-------
 lldb/include/lldb/Target/ThreadPlanPython.h   |  2 +
 lldb/include/lldb/lldb-forward.h              |  3 +
 .../Python/OperatingSystemPython.cpp          |  3 +-
 .../Process/scripted/ScriptedProcess.cpp      |  3 +-
 .../Process/scripted/ScriptedThread.cpp       |  4 +-
 .../OperatingSystemPythonInterface.cpp        | 10 ++-
 .../OperatingSystemPythonInterface.h          |  7 +-
 .../ScriptedPlatformPythonInterface.cpp       | 25 ------
 .../ScriptedPlatformPythonInterface.h         | 11 +--
 .../ScriptedProcessPythonInterface.cpp        | 25 ------
 .../ScriptedProcessPythonInterface.h          |  9 +-
 .../Interfaces/ScriptedPythonInterface.h      | 61 +++++++++++++
 .../ScriptedThreadPythonInterface.cpp         | 64 +++++++-------
 .../ScriptedThreadPythonInterface.h           |  5 --
 .../Python/ScriptInterpreterPython.cpp        | 88 -------------------
 .../Python/ScriptInterpreterPythonImpl.h      | 19 ----
 lldb/source/Target/ThreadPlanPython.cpp       | 38 ++++----
 23 files changed, 209 insertions(+), 285 deletions(-)
 create mode 100644 lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h

diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h
index 948f763e95ecea4..31b1087fe93098f 100644
--- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h
@@ -25,10 +25,12 @@ class ScriptedInterface {
   ScriptedInterface() = default;
   virtual ~ScriptedInterface() = default;
 
-  virtual StructuredData::GenericSP
-  CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx,
-                     StructuredData::DictionarySP args_sp,
-                     StructuredData::Generic *script_obj = nullptr) = 0;
+  template <typename ...Args>
+  StructuredData::GenericSP
+  CreatePluginObject(llvm::StringRef class_name,
+                     StructuredData::Generic *script_obj, Args && ...args) {
+    llvm_unreachable("Not implemented.");
+  }
 
   StructuredData::GenericSP GetScriptObjectInstance() {
     return m_object_instance_sp;
diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h
index c687cabfe0c1278..cf7ba42af77d02a 100644
--- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h
@@ -19,11 +19,11 @@
 namespace lldb_private {
 class ScriptedPlatformInterface : virtual public ScriptedInterface {
 public:
+  template <typename ...Args>
   StructuredData::GenericSP
-  CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx,
-                     StructuredData::DictionarySP args_sp,
-                     StructuredData::Generic *script_obj = nullptr) override {
-    return {};
+  CreatePluginObject(llvm::StringRef class_name,
+                     StructuredData::Generic *script_obj, Args &&...args) {
+    llvm_unreachable("Not implemented.");
   }
 
   virtual StructuredData::DictionarySP ListProcesses() { return {}; }
diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedProcessInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedProcessInterface.h
index 68756c4d9ac858d..9aec14c92f2c3ba 100644
--- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedProcessInterface.h
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedProcessInterface.h
@@ -21,11 +21,11 @@
 namespace lldb_private {
 class ScriptedProcessInterface : virtual public ScriptedInterface {
 public:
+  template <typename ...Args>
   StructuredData::GenericSP
-  CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx,
-                     StructuredData::DictionarySP args_sp,
-                     StructuredData::Generic *script_obj = nullptr) override {
-    return {};
+  CreatePluginObject(llvm::StringRef class_name,
+                     StructuredData::Generic *script_obj, Args &&...args) {
+    llvm_unreachable("Not implemented.");
   }
 
   virtual StructuredData::DictionarySP GetCapabilities() { return {}; }
diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadInterface.h
index 781df51a213229a..9c6e46cb7f59ebe 100644
--- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadInterface.h
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadInterface.h
@@ -20,11 +20,11 @@
 namespace lldb_private {
 class ScriptedThreadInterface : virtual public ScriptedInterface {
 public:
+  template <typename ...Args>
   StructuredData::GenericSP
-  CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx,
-                     StructuredData::DictionarySP args_sp,
-                     StructuredData::Generic *script_obj = nullptr) override {
-    return {};
+  CreatePluginObject(llvm::StringRef class_name,
+                     StructuredData::Generic *script_obj, Args &&...args) {
+    llvm_unreachable("Not implemented.");
   }
 
   virtual lldb::tid_t GetThreadID() { return LLDB_INVALID_THREAD_ID; }
diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h
new file mode 100644
index 000000000000000..46da47fd460bf0e
--- /dev/null
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h
@@ -0,0 +1,42 @@
+//===-- ScriptedThreadInterface.h -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_INTERPRETER_INTERFACES_SCRIPTEDTHREADPLANINTERFACE_H
+#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDTHREADPLANINTERFACE_H
+
+#include "ScriptedInterface.h"
+#include "lldb/Core/StructuredDataImpl.h"
+
+#include "lldb/lldb-private.h"
+
+#include <optional>
+#include <string>
+
+namespace lldb_private {
+class ScriptedThreadPlanInterface : virtual public ScriptedInterface {
+public:
+  template <typename ...Args>
+  StructuredData::GenericSP
+  CreatePluginObject(llvm::StringRef class_name,
+                     StructuredData::Generic *script_obj, Args &&...args) {
+    llvm_unreachable("Not implemented.");
+  }
+  
+  virtual bool ExplainsStop(Event *event) { return true; }
+
+  virtual bool ShouldStop(Event *event) { return true; }
+
+  virtual bool IsStale() { return true; };
+
+  virtual lldb::StateType GetRunState() { return lldb::eStateStepping; }
+
+  bool GetStopDescription(lldb_private::Stream *s) { return true; }
+};
+} // namespace lldb_private
+
+#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDTHREADPLANINTERFACE_H
diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
index 57a1962441e9510..cc4ff96de747c01 100644
--- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -25,6 +25,7 @@
 #include "lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h"
 #include "lldb/Interpreter/Interfaces/ScriptedProcessInterface.h"
 #include "lldb/Interpreter/Interfaces/ScriptedThreadInterface.h"
+#include "lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h"
 #include "lldb/Interpreter/ScriptObject.h"
 #include "lldb/Utility/Broadcaster.h"
 #include "lldb/Utility/Status.h"
@@ -283,42 +284,6 @@ class ScriptInterpreter : public PluginInterface {
     return StructuredData::ObjectSP();
   }
 
-  virtual bool
-  ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
-                                 Event *event, bool &script_error) {
-    script_error = true;
-    return true;
-  }
-
-  virtual bool
-  ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp,
-                               Event *event, bool &script_error) {
-    script_error = true;
-    return true;
-  }
-
-  virtual bool
-  ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp,
-                            bool &script_error) {
-    script_error = true;
-    return true;
-  }
-
-  virtual lldb::StateType
-  ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp,
-                                bool &script_error) {
-    script_error = true;
-    return lldb::eStateStepping;
-  }
-
-  virtual bool
-  ScriptedThreadPlanGetStopDescription(StructuredData::ObjectSP implementor_sp,
-                                       lldb_private::Stream *stream,
-                                       bool &script_error) {
-    script_error = true;
-    return false;
-  }
-
   virtual StructuredData::GenericSP
   CreateScriptedBreakpointResolver(const char *class_name,
                                    const StructuredDataImpl &args_data,
@@ -587,6 +552,10 @@ class ScriptInterpreter : public PluginInterface {
   virtual lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() {
     return std::make_shared<ScriptedThreadInterface>();
   }
+  
+  virtual lldb::ScriptedThreadPlanInterfaceSP CreateScriptedThreadPlanInterface() {
+    return std::make_shared<ScriptedThreadPlanInterface>();
+  }
 
   virtual lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() {
     return std::make_shared<OperatingSystemInterface>();
diff --git a/lldb/include/lldb/Target/ThreadPlanPython.h b/lldb/include/lldb/Target/ThreadPlanPython.h
index 64854d66b8f2589..da106faf951db1c 100644
--- a/lldb/include/lldb/Target/ThreadPlanPython.h
+++ b/lldb/include/lldb/Target/ThreadPlanPython.h
@@ -13,6 +13,7 @@
 #include <string>
 
 #include "lldb/Core/StructuredDataImpl.h"
+#include "lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/StopInfo.h"
 #include "lldb/Target/Target.h"
@@ -70,6 +71,7 @@ class ThreadPlanPython : public ThreadPlan {
   StreamString m_stop_description; // Cache the stop description here
   bool m_did_push;
   bool m_stop_others;
+  lldb::ScriptedThreadPlanInterfaceSP m_interface;
 
   ThreadPlanPython(const ThreadPlanPython &) = delete;
   const ThreadPlanPython &operator=(const ThreadPlanPython &) = delete;
diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index aa099d4abc3b09f..6138e6fe5a60b45 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -185,6 +185,7 @@ class ScriptedMetadata;
 class ScriptedPlatformInterface;
 class ScriptedProcessInterface;
 class ScriptedThreadInterface;
+class ScriptedThreadPlanInterface;
 class ScriptedSyntheticChildren;
 class SearchFilter;
 class Section;
@@ -393,6 +394,8 @@ typedef std::unique_ptr<lldb_private::ScriptedProcessInterface>
     ScriptedProcessInterfaceUP;
 typedef std::shared_ptr<lldb_private::ScriptedThreadInterface>
     ScriptedThreadInterfaceSP;
+typedef std::shared_ptr<lldb_private::ScriptedThreadPlanInterface>
+    ScriptedThreadPlanInterfaceSP;
 typedef std::shared_ptr<lldb_private::Section> SectionSP;
 typedef std::unique_ptr<lldb_private::SectionList> SectionListUP;
 typedef std::weak_ptr<lldb_private::Section> SectionWP;
diff --git a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
index 9a5dd515489231c..28739a07de7da5b 100644
--- a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
+++ b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
@@ -116,8 +116,7 @@ OperatingSystemPython::OperatingSystemPython(lldb_private::Process *process,
 
   ExecutionContext exe_ctx(process);
   StructuredData::GenericSP owned_script_object_sp =
-      operating_system_interface->CreatePluginObject(os_plugin_class_name,
-                                                     exe_ctx, nullptr);
+      operating_system_interface->CreatePluginObject(os_plugin_class_name, nullptr, exe_ctx);
 
   if (!owned_script_object_sp)
     //    return llvm::createStringError(llvm::inconvertibleErrorCode(),
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
index e99a2a08bd50d8f..614c699f55d3d03 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
+++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
@@ -109,8 +109,7 @@ ScriptedProcess::ScriptedProcess(lldb::TargetSP target_sp,
 
   // Create process script object
   StructuredData::GenericSP object_sp = GetInterface().CreatePluginObject(
-      m_scripted_metadata.GetClassName(), exe_ctx,
-      m_scripted_metadata.GetArgsSP());
+      m_scripted_metadata.GetClassName(), nullptr, exe_ctx, m_scripted_metadata.GetArgsSP());
 
   if (!object_sp || !object_sp->IsValid()) {
     error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s",
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
index 684375957d24760..e4af8e95a753bd8 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
+++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
@@ -58,8 +58,8 @@ ScriptedThread::Create(ScriptedProcess &process,
   ExecutionContext exe_ctx(process);
   StructuredData::GenericSP owned_script_object_sp =
       scripted_thread_interface->CreatePluginObject(
-          thread_class_name, exe_ctx, process.m_scripted_metadata.GetArgsSP(),
-          script_object);
+          thread_class_name, script_object,
+          exe_ctx, process.m_scripted_metadata.GetArgsSP());
 
   if (!owned_script_object_sp)
     return llvm::createStringError(llvm::inconvertibleErrorCode(),
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.cpp
index 45804d5d019d79d..4efbbbfe40870fb 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.cpp
@@ -29,10 +29,12 @@ OperatingSystemPythonInterface::OperatingSystemPythonInterface(
     : OperatingSystemInterface(), ScriptedThreadPythonInterface(interpreter) {}
 
 StructuredData::GenericSP OperatingSystemPythonInterface::CreatePluginObject(
-    llvm::StringRef class_name, ExecutionContext &exe_ctx,
-    StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
-  return ScriptedThreadPythonInterface::CreatePluginObject(class_name, exe_ctx,
-                                                           args_sp, script_obj);
+    llvm::StringRef class_name, StructuredData::Generic *script_obj,
+    ExecutionContext &exe_ctx, StructuredData::DictionarySP args_sp) {
+  return ScriptedPythonInterface::CreatePluginObject(class_name,
+                                                           script_obj,
+                                                           exe_ctx,
+                                                           args_sp);
 }
 
 StructuredData::DictionarySP
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.h
index a69557ad7c43469..87fded49f796442 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.h
@@ -25,9 +25,10 @@ class OperatingSystemPythonInterface
   OperatingSystemPythonInterface(ScriptInterpreterPythonImpl &interpreter);
 
   StructuredData::GenericSP
-  CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx,
-                     StructuredData::DictionarySP args_sp,
-                     StructuredData::Generic *script_obj = nullptr) override;
+  CreatePluginObject(llvm::StringRef class_name,
+                     StructuredData::Generic *script_obj,
+                     ExecutionContext &exe_ctx,
+                     StructuredData::DictionarySP args_sp);
 
   StructuredData::DictionarySP CreateThread(lldb::tid_t tid,
                                             lldb::addr_t context) override;
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.cpp
index 9bed33516915d08..f2a65583927d4af 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.cpp
@@ -29,31 +29,6 @@ ScriptedPlatformPythonInterface::ScriptedPlatformPythonInterface(
     ScriptInterpreterPythonImpl &interpreter)
     : ScriptedPlatformInterface(), ScriptedPythonInterface(interpreter) {}
 
-StructuredData::GenericSP ScriptedPlatformPythonInterface::CreatePluginObject(
-    llvm::StringRef class_name, ExecutionContext &exe_ctx,
-    StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
-  if (class_name.empty())
-    return {};
-
-  StructuredDataImpl args_impl(args_sp);
-  std::string error_string;
-
-  Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
-                 Locker::FreeLock);
-
-  lldb::ExecutionContextRefSP exe_ctx_ref_sp =
-      std::make_shared<ExecutionContextRef>(exe_ctx);
-
-  PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateScriptedObject(
-      class_name.str().c_str(), m_interpreter.GetDictionaryName(),
-      exe_ctx_ref_sp, args_impl, error_string);
-
-  m_object_instance_sp =
-      StructuredData::GenericSP(new StructuredPythonObject(std::move(ret_val)));
-
-  return m_object_instance_sp;
-}
-
 StructuredData::DictionarySP ScriptedPlatformPythonInterface::ListProcesses() {
   Status error;
   StructuredData::DictionarySP dict_sp =
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.h
index 02deecd15ede062..45e6c7fc1c1b979 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.h
@@ -21,12 +21,13 @@ class ScriptedPlatformPythonInterface : public ScriptedPlatformInterface,
                                         public ScriptedPythonInterface {
 public:
   ScriptedPlatformPythonInterface(ScriptInterpreterPythonImpl &interpreter);
-
+                                          
+  template <typename ...Args>
   StructuredData::GenericSP
-  CreatePluginObject(const llvm::StringRef class_name,
-                     ExecutionContext &exe_ctx,
-                     StructuredData::DictionarySP args_sp,
-                     StructuredData::Generic *script_obj = nullptr) override;
+  CreatePluginObject(llvm::StringRef class_name,
+                     StructuredData::Generic *script_obj, Args ...args) {
+    return ScriptedPythonInterface::CreatePluginObject(class_name, std::forward<Args>(args)...);
+  }
 
   StructuredData::DictionarySP ListProcesses() override;
 
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.cpp
index 63a4db1ff5973e7..90549c353bafc43 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.cpp
@@ -33,31 +33,6 @@ ScriptedProcessPythonInterface::ScriptedProcessPythonInterface(
     ScriptInterpreterPythonImpl &interpreter)
     : ScriptedProcessInterface(), ScriptedPythonInterface(interpreter) {}
 
-StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject(
-    llvm::StringRef class_name, ExecutionContext &exe_ctx,
-    StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
-  if (class_name.empty())
-    return {};
-
-  StructuredDataImpl args_impl(args_sp);
-  std::string error_string;
-
-  Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
-                 Locker::FreeLock);
-
-  lldb::ExecutionContextRefSP exe_ctx_ref_sp =
-      std::make_shared<ExecutionContextRef>(exe_ctx);
-
-  PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateScriptedObject(
-      class_name.str().c_str(), m_interpreter.GetDictionaryName(),
-      exe_ctx_ref_sp, args_impl, error_string);
-
-  m_object_instance_sp =
-      StructuredData::GenericSP(new StructuredPythonObject(std::move(ret_val)));
-
-  return m_object_instance_sp;
-}
-
 StructuredData::DictionarySP ScriptedProcessPythonInterface::GetCapabilities() {
   Status error;
   StructuredData::DictionarySP dict =
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.h
index 11330f5591b74e6..4555cc0b1e84b9a 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.h
@@ -23,11 +23,12 @@ class ScriptedProcessPythonInterface : public ScriptedProcessInterface,
 public:
   ScriptedProcessPythonInterface(ScriptInterpreterPythonImpl &interpreter);
 
+  template <typename ...Args>
   StructuredData::GenericSP
-  CreatePluginObject(const llvm::StringRef class_name,
-                     ExecutionContext &exe_ctx,
-                     StructuredData::DictionarySP args_sp,
-                     StructuredData::Generic *script_obj = nullptr) override;
+  CreatePluginObject(llvm::StringRef class_name,
+                     StructuredData::Generic *script_obj, Args ...args) {
+    return ScriptedPythonInterface::CreatePluginObject(class_name, std::forward<Args>(args)...);
+  }
 
   StructuredData::DictionarySP GetCapabilities() override;
 
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
index 9163b8f6aede7d1..706cfee32dc2370 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
@@ -30,6 +30,67 @@ class ScriptInterpreterPythonImpl;
 class ScriptedPythonInterface : virtual public ScriptedInterface {
 public:
   ScriptedPythonInterface(ScriptInterpreterPythonImpl &interpreter);
+  
+  template <typename ...Args>
+  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())
+      return {};
+
+    Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+                   Locker::FreeLock);
+    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 {};
+    }
+    
+    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 {};
+    }
+
+    PythonObject result = {};
+//    switch (arg_info.get().max_positional_args) {
+//      case 1:
+//        // FIXME: Since this is used by different scripting affordances, they can have different number
+//        // of argument but also different types of arguments (i.e SBExecutionContect vs SBProcess)
+//        // We need to have a more reliable way to forward positional arguments.
+//        result = pfunc(SWIGBridge::ToSWIGWrapper(exe_ctx_sp->GetProcessSP()));
+//        break;
+//      case 2:
+//        result = pfunc(SWIGBridge::ToSWIGWrapper(exe_ctx_sp), SWIGBridge::ToSWIGWrapper(args_impl));
+//        break;
+//      default:
+//        error_string.assign("wrong number of arguments in __init__, should be 2 "
+//                            "(not including self)");
+//        break;
+//    }
+    
+    if (!result.IsValid())
+      return {};
+
+    m_object_instance_sp = StructuredData::GenericSP(new StructuredPythonObject(std::move(result)));
+    return m_object_instance_sp;
+  }
+  
   ~ScriptedPythonInterface() override = default;
 
 protected:
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp
index 6addcd46e045efc..1721565b3e2f3f2 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp
@@ -29,38 +29,38 @@ ScriptedThreadPythonInterface::ScriptedThreadPythonInterface(
     ScriptInterpreterPythonImpl &interpreter)
     : ScriptedThreadInterface(), ScriptedPythonInterface(interpreter) {}
 
-StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject(
-    const llvm::StringRef class_name, ExecutionContext &exe_ctx,
-    StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
-  if (class_name.empty() && !script_obj)
-    return {};
-
-  StructuredDataImpl args_impl(args_sp);
-  std::string error_string;
-
-  Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
-                 Locker::FreeLock);
-
-  PythonObject ret_val;
-
-  if (!script_obj) {
-    lldb::ExecutionContextRefSP exe_ctx_ref_sp =
-        std::make_shared<ExecutionContextRef>(exe_ctx);
-    ret_val = SWIGBridge::LLDBSwigPythonCreateScriptedObject(
-        class_name.str().c_str(), m_interpreter.GetDictionaryName(),
-        exe_ctx_ref_sp, args_impl, error_string);
-  } else
-    ret_val = PythonObject(PyRefType::Borrowed,
-                           static_cast<PyObject *>(script_obj->GetValue()));
-
-  if (!ret_val)
-    return {};
-
-  m_object_instance_sp =
-      StructuredData::GenericSP(new StructuredPythonObject(std::move(ret_val)));
-
-  return m_object_instance_sp;
-}
+//StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject(
+//    const llvm::StringRef class_name, ExecutionContext &exe_ctx,
+//    StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
+//  if (class_name.empty() && !script_obj)
+//    return {};
+//
+//  StructuredDataImpl args_impl(args_sp);
+//  std::string error_string;
+//
+//  Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+//                 Locker::FreeLock);
+//
+//  PythonObject ret_val;
+//
+//  if (!script_obj) {
+//    lldb::ExecutionContextRefSP exe_ctx_ref_sp =
+//        std::make_shared<ExecutionContextRef>(exe_ctx);
+//    ret_val = SWIGBridge::LLDBSwigPythonCreateScriptedObject(
+//        class_name.str().c_str(), m_interpreter.GetDictionaryName(),
+//        exe_ctx_ref_sp, args_impl, error_string);
+//  } else
+//    ret_val = PythonObject(PyRefType::Borrowed,
+//                           static_cast<PyObject *>(script_obj->GetValue()));
+//
+//  if (!ret_val)
+//    return {};
+//
+//  m_object_instance_sp =
+//      StructuredData::GenericSP(new StructuredPythonObject(std::move(ret_val)));
+//
+//  return m_object_instance_sp;
+//}
 
 lldb::tid_t ScriptedThreadPythonInterface::GetThreadID() {
   Status error;
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.h
index b63760fd5b5713d..72293538c779309 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.h
@@ -23,11 +23,6 @@ class ScriptedThreadPythonInterface : public ScriptedThreadInterface,
 public:
   ScriptedThreadPythonInterface(ScriptInterpreterPythonImpl &interpreter);
 
-  StructuredData::GenericSP
-  CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx,
-                     StructuredData::DictionarySP args_sp,
-                     StructuredData::Generic *script_obj = nullptr) override;
-
   lldb::tid_t GetThreadID() override;
 
   std::optional<std::string> GetName() override;
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index a57c8e4984ad8a8..63ac3b41a4dce2e 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -1566,94 +1566,6 @@ StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan(
       new StructuredPythonObject(std::move(ret_val)));
 }
 
-bool ScriptInterpreterPythonImpl::ScriptedThreadPlanExplainsStop(
-    StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) {
-  bool explains_stop = true;
-  StructuredData::Generic *generic = nullptr;
-  if (implementor_sp)
-    generic = implementor_sp->GetAsGeneric();
-  if (generic) {
-    Locker py_lock(this,
-                   Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
-    explains_stop = SWIGBridge::LLDBSWIGPythonCallThreadPlan(
-        generic->GetValue(), "explains_stop", event, script_error);
-    if (script_error)
-      return true;
-  }
-  return explains_stop;
-}
-
-bool ScriptInterpreterPythonImpl::ScriptedThreadPlanShouldStop(
-    StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) {
-  bool should_stop = true;
-  StructuredData::Generic *generic = nullptr;
-  if (implementor_sp)
-    generic = implementor_sp->GetAsGeneric();
-  if (generic) {
-    Locker py_lock(this,
-                   Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
-    should_stop = SWIGBridge::LLDBSWIGPythonCallThreadPlan(
-        generic->GetValue(), "should_stop", event, script_error);
-    if (script_error)
-      return true;
-  }
-  return should_stop;
-}
-
-bool ScriptInterpreterPythonImpl::ScriptedThreadPlanIsStale(
-    StructuredData::ObjectSP implementor_sp, bool &script_error) {
-  bool is_stale = true;
-  StructuredData::Generic *generic = nullptr;
-  if (implementor_sp)
-    generic = implementor_sp->GetAsGeneric();
-  if (generic) {
-    Locker py_lock(this,
-                   Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
-    is_stale = SWIGBridge::LLDBSWIGPythonCallThreadPlan(
-        generic->GetValue(), "is_stale", (Event *)nullptr, script_error);
-    if (script_error)
-      return true;
-  }
-  return is_stale;
-}
-
-lldb::StateType ScriptInterpreterPythonImpl::ScriptedThreadPlanGetRunState(
-    StructuredData::ObjectSP implementor_sp, bool &script_error) {
-  bool should_step = false;
-  StructuredData::Generic *generic = nullptr;
-  if (implementor_sp)
-    generic = implementor_sp->GetAsGeneric();
-  if (generic) {
-    Locker py_lock(this,
-                   Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
-    should_step = SWIGBridge::LLDBSWIGPythonCallThreadPlan(
-        generic->GetValue(), "should_step", (Event *)nullptr, script_error);
-    if (script_error)
-      should_step = true;
-  }
-  if (should_step)
-    return lldb::eStateStepping;
-  return lldb::eStateRunning;
-}
-
-bool
-ScriptInterpreterPythonImpl::ScriptedThreadPlanGetStopDescription(
-    StructuredData::ObjectSP implementor_sp, lldb_private::Stream *stream,
-    bool &script_error) {
-  StructuredData::Generic *generic = nullptr;
-  if (implementor_sp)
-    generic = implementor_sp->GetAsGeneric();
-  if (!generic) {
-    script_error = true;
-    return false;
-  }
-  Locker py_lock(this,
-                   Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
-  return SWIGBridge::LLDBSWIGPythonCallThreadPlan(
-      generic->GetValue(), "stop_description", stream, script_error);
-}
-
-
 StructuredData::GenericSP
 ScriptInterpreterPythonImpl::CreateScriptedBreakpointResolver(
     const char *class_name, const StructuredDataImpl &args_data,
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
index a33499816d8d38c..7daa602eec33c3b 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -86,25 +86,6 @@ class ScriptInterpreterPythonImpl : public ScriptInterpreterPython {
   StructuredData::ObjectSP
   CreateStructuredDataFromScriptObject(ScriptObject obj) override;
 
-  bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
-                                      Event *event,
-                                      bool &script_error) override;
-
-  bool ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp,
-                                    Event *event, bool &script_error) override;
-
-  bool ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp,
-                                 bool &script_error) override;
-
-  lldb::StateType
-  ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp,
-                                bool &script_error) override;
-
-  bool
-  ScriptedThreadPlanGetStopDescription(StructuredData::ObjectSP implementor_sp,
-                                lldb_private::Stream *s,
-                                bool &script_error) override;
-
   StructuredData::GenericSP
   CreateScriptedBreakpointResolver(const char *class_name,
                                    const StructuredDataImpl &args_data,
diff --git a/lldb/source/Target/ThreadPlanPython.cpp b/lldb/source/Target/ThreadPlanPython.cpp
index d6de6b3c3cf0497..d7e0d59ea205cd3 100644
--- a/lldb/source/Target/ThreadPlanPython.cpp
+++ b/lldb/source/Target/ThreadPlanPython.cpp
@@ -32,6 +32,15 @@ ThreadPlanPython::ThreadPlanPython(Thread &thread, const char *class_name,
                  eVoteNoOpinion, eVoteNoOpinion),
       m_class_name(class_name), m_args_data(args_data), m_did_push(false),
       m_stop_others(false) {
+  ScriptInterpreter* interpreter = GetScriptInterpreter();
+  if (!interpreter) {
+    SetPlanComplete(false);
+    // FIXME: error handling
+    return;
+  }
+
+        
+  m_interface = interpreter->CreateScriptedThreadPlanInterface();
   SetIsControllingPlan(true);
   SetOkayToDiscard(true);
   SetPrivate(false);
@@ -80,10 +89,9 @@ bool ThreadPlanPython::ShouldStop(Event *event_ptr) {
     ScriptInterpreter *script_interp = GetScriptInterpreter();
     if (script_interp) {
       bool script_error;
-      should_stop = script_interp->ScriptedThreadPlanShouldStop(
-          m_implementation_sp, event_ptr, script_error);
-      if (script_error)
-        SetPlanComplete(false);
+      should_stop = m_interface->ShouldStop(event_ptr);
+//      if (script_error)
+//        SetPlanComplete(false);
     }
   }
   return should_stop;
@@ -99,10 +107,9 @@ bool ThreadPlanPython::IsPlanStale() {
     ScriptInterpreter *script_interp = GetScriptInterpreter();
     if (script_interp) {
       bool script_error;
-      is_stale = script_interp->ScriptedThreadPlanIsStale(m_implementation_sp,
-                                                          script_error);
-      if (script_error)
-        SetPlanComplete(false);
+      is_stale = m_interface->IsStale();
+//      if (script_error)
+//        SetPlanComplete(false);
     }
   }
   return is_stale;
@@ -118,10 +125,9 @@ bool ThreadPlanPython::DoPlanExplainsStop(Event *event_ptr) {
     ScriptInterpreter *script_interp = GetScriptInterpreter();
     if (script_interp) {
       bool script_error;
-      explains_stop = script_interp->ScriptedThreadPlanExplainsStop(
-          m_implementation_sp, event_ptr, script_error);
-      if (script_error)
-        SetPlanComplete(false);
+      explains_stop = m_interface->ExplainsStop(event_ptr);
+//      if (script_error)
+//        SetPlanComplete(false);
     }
   }
   return explains_stop;
@@ -154,8 +160,7 @@ lldb::StateType ThreadPlanPython::GetPlanRunState() {
     ScriptInterpreter *script_interp = GetScriptInterpreter();
     if (script_interp) {
       bool script_error;
-      run_state = script_interp->ScriptedThreadPlanGetRunState(
-          m_implementation_sp, script_error);
+      run_state = m_interface->GetRunState();
     }
   }
   return run_state;
@@ -168,9 +173,8 @@ void ThreadPlanPython::GetDescription(Stream *s, lldb::DescriptionLevel level) {
   if (m_implementation_sp) {
     ScriptInterpreter *script_interp = GetScriptInterpreter();
     if (script_interp) {
-      bool script_error;
-      bool added_desc = script_interp->ScriptedThreadPlanGetStopDescription(
-          m_implementation_sp, s, script_error);
+      bool script_error = true;
+      bool added_desc = m_interface->GetStopDescription(s);
       if (script_error || !added_desc)
         s->Printf("Python thread plan implemented by class %s.",
             m_class_name.c_str());



More information about the lldb-commits mailing list