xref: /src/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
15f29bb8aSDimitry Andric //===-- ScriptInterpreterPythonImpl.h ---------------------------*- C++ -*-===//
25f29bb8aSDimitry Andric //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65f29bb8aSDimitry Andric //
75f29bb8aSDimitry Andric //===----------------------------------------------------------------------===//
85f29bb8aSDimitry Andric 
9344a3780SDimitry Andric #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H
10344a3780SDimitry Andric #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H
11344a3780SDimitry Andric 
12706b4fc4SDimitry Andric #include "lldb/Host/Config.h"
135f29bb8aSDimitry Andric 
14706b4fc4SDimitry Andric #if LLDB_ENABLE_PYTHON
155f29bb8aSDimitry Andric 
165f29bb8aSDimitry Andric #include "lldb-python.h"
175f29bb8aSDimitry Andric 
185f29bb8aSDimitry Andric #include "PythonDataObjects.h"
195f29bb8aSDimitry Andric #include "ScriptInterpreterPython.h"
205f29bb8aSDimitry Andric 
215f29bb8aSDimitry Andric #include "lldb/Host/Terminal.h"
225f29bb8aSDimitry Andric #include "lldb/Utility/StreamString.h"
235f29bb8aSDimitry Andric 
245f29bb8aSDimitry Andric #include "llvm/ADT/STLExtras.h"
255f29bb8aSDimitry Andric #include "llvm/ADT/StringRef.h"
265f29bb8aSDimitry Andric 
275f29bb8aSDimitry Andric namespace lldb_private {
285f29bb8aSDimitry Andric class IOHandlerPythonInterpreter;
295f29bb8aSDimitry Andric class ScriptInterpreterPythonImpl : public ScriptInterpreterPython {
305f29bb8aSDimitry Andric public:
315f29bb8aSDimitry Andric   friend class IOHandlerPythonInterpreter;
325f29bb8aSDimitry Andric 
335f29bb8aSDimitry Andric   ScriptInterpreterPythonImpl(Debugger &debugger);
345f29bb8aSDimitry Andric 
355f29bb8aSDimitry Andric   ~ScriptInterpreterPythonImpl() override;
365f29bb8aSDimitry Andric 
375f29bb8aSDimitry Andric   bool Interrupt() override;
385f29bb8aSDimitry Andric 
395f29bb8aSDimitry Andric   bool ExecuteOneLine(
405f29bb8aSDimitry Andric       llvm::StringRef command, CommandReturnObject *result,
415f29bb8aSDimitry Andric       const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
425f29bb8aSDimitry Andric 
435f29bb8aSDimitry Andric   void ExecuteInterpreterLoop() override;
445f29bb8aSDimitry Andric 
455f29bb8aSDimitry Andric   bool ExecuteOneLineWithReturn(
465f29bb8aSDimitry Andric       llvm::StringRef in_string,
475f29bb8aSDimitry Andric       ScriptInterpreter::ScriptReturnType return_type, void *ret_value,
485f29bb8aSDimitry Andric       const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
495f29bb8aSDimitry Andric 
505f29bb8aSDimitry Andric   lldb_private::Status ExecuteMultipleLines(
515f29bb8aSDimitry Andric       const char *in_string,
525f29bb8aSDimitry Andric       const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
535f29bb8aSDimitry Andric 
545f29bb8aSDimitry Andric   Status
555f29bb8aSDimitry Andric   ExportFunctionDefinitionToInterpreter(StringList &function_def) override;
565f29bb8aSDimitry Andric 
575f29bb8aSDimitry Andric   bool GenerateTypeScriptFunction(StringList &input, std::string &output,
585f29bb8aSDimitry Andric                                   const void *name_token = nullptr) override;
595f29bb8aSDimitry Andric 
605f29bb8aSDimitry Andric   bool GenerateTypeSynthClass(StringList &input, std::string &output,
615f29bb8aSDimitry Andric                               const void *name_token = nullptr) override;
625f29bb8aSDimitry Andric 
635f29bb8aSDimitry Andric   bool GenerateTypeSynthClass(const char *oneliner, std::string &output,
645f29bb8aSDimitry Andric                               const void *name_token = nullptr) override;
655f29bb8aSDimitry Andric 
665f29bb8aSDimitry Andric   // use this if the function code is just a one-liner script
675f29bb8aSDimitry Andric   bool GenerateTypeScriptFunction(const char *oneliner, std::string &output,
685f29bb8aSDimitry Andric                                   const void *name_token = nullptr) override;
695f29bb8aSDimitry Andric 
705f29bb8aSDimitry Andric   bool GenerateScriptAliasFunction(StringList &input,
715f29bb8aSDimitry Andric                                    std::string &output) override;
725f29bb8aSDimitry Andric 
735f29bb8aSDimitry Andric   StructuredData::ObjectSP
745f29bb8aSDimitry Andric   CreateSyntheticScriptedProvider(const char *class_name,
755f29bb8aSDimitry Andric                                   lldb::ValueObjectSP valobj) override;
765f29bb8aSDimitry Andric 
775f29bb8aSDimitry Andric   StructuredData::GenericSP
785f29bb8aSDimitry Andric   CreateScriptCommandObject(const char *class_name) override;
795f29bb8aSDimitry Andric 
805f29bb8aSDimitry Andric   StructuredData::ObjectSP
817fa27ce4SDimitry Andric   CreateStructuredDataFromScriptObject(ScriptObject obj) override;
827fa27ce4SDimitry Andric 
835f29bb8aSDimitry Andric   StructuredData::GenericSP
845f29bb8aSDimitry Andric   CreateScriptedBreakpointResolver(const char *class_name,
8577fc4c14SDimitry Andric                                    const StructuredDataImpl &args_data,
865f29bb8aSDimitry Andric                                    lldb::BreakpointSP &bkpt_sp) override;
875f29bb8aSDimitry Andric   bool ScriptedBreakpointResolverSearchCallback(
885f29bb8aSDimitry Andric       StructuredData::GenericSP implementor_sp,
895f29bb8aSDimitry Andric       SymbolContext *sym_ctx) override;
905f29bb8aSDimitry Andric 
915f29bb8aSDimitry Andric   lldb::SearchDepth ScriptedBreakpointResolverSearchDepth(
925f29bb8aSDimitry Andric       StructuredData::GenericSP implementor_sp) override;
935f29bb8aSDimitry Andric 
945f29bb8aSDimitry Andric   StructuredData::GenericSP
95b60736ecSDimitry Andric   CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name,
9677fc4c14SDimitry Andric                          const StructuredDataImpl &args_data,
9777fc4c14SDimitry Andric                          Status &error) override;
98b60736ecSDimitry Andric 
99b60736ecSDimitry Andric   bool ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp,
100b60736ecSDimitry Andric                                   ExecutionContext &exc_ctx,
101b60736ecSDimitry Andric                                   lldb::StreamSP stream_sp) override;
102b60736ecSDimitry Andric 
103b60736ecSDimitry Andric   StructuredData::GenericSP
1045f29bb8aSDimitry Andric   CreateFrameRecognizer(const char *class_name) override;
1055f29bb8aSDimitry Andric 
1065f29bb8aSDimitry Andric   lldb::ValueObjectListSP
1075f29bb8aSDimitry Andric   GetRecognizedArguments(const StructuredData::ObjectSP &implementor,
1085f29bb8aSDimitry Andric                          lldb::StackFrameSP frame_sp) override;
1095f29bb8aSDimitry Andric 
1107fa27ce4SDimitry Andric   lldb::ScriptedProcessInterfaceUP CreateScriptedProcessInterface() override;
1117fa27ce4SDimitry Andric 
112b1c73532SDimitry Andric   lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override;
1135f29bb8aSDimitry Andric 
114ac9a064cSDimitry Andric   lldb::ScriptedThreadPlanInterfaceSP
115ac9a064cSDimitry Andric   CreateScriptedThreadPlanInterface() override;
116ac9a064cSDimitry Andric 
117b1c73532SDimitry Andric   lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() override;
1185f29bb8aSDimitry Andric 
1195f29bb8aSDimitry Andric   StructuredData::ObjectSP
1205f29bb8aSDimitry Andric   LoadPluginModule(const FileSpec &file_spec,
1215f29bb8aSDimitry Andric                    lldb_private::Status &error) override;
1225f29bb8aSDimitry Andric 
1235f29bb8aSDimitry Andric   StructuredData::DictionarySP
1245f29bb8aSDimitry Andric   GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target,
1255f29bb8aSDimitry Andric                      const char *setting_name,
1265f29bb8aSDimitry Andric                      lldb_private::Status &error) override;
1275f29bb8aSDimitry Andric 
1285f29bb8aSDimitry Andric   size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor,
1295f29bb8aSDimitry Andric                               uint32_t max) override;
1305f29bb8aSDimitry Andric 
1315f29bb8aSDimitry Andric   lldb::ValueObjectSP
1325f29bb8aSDimitry Andric   GetChildAtIndex(const StructuredData::ObjectSP &implementor,
1335f29bb8aSDimitry Andric                   uint32_t idx) override;
1345f29bb8aSDimitry Andric 
1355f29bb8aSDimitry Andric   int GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor,
1365f29bb8aSDimitry Andric                               const char *child_name) override;
1375f29bb8aSDimitry Andric 
1385f29bb8aSDimitry Andric   bool UpdateSynthProviderInstance(
1395f29bb8aSDimitry Andric       const StructuredData::ObjectSP &implementor) override;
1405f29bb8aSDimitry Andric 
1415f29bb8aSDimitry Andric   bool MightHaveChildrenSynthProviderInstance(
1425f29bb8aSDimitry Andric       const StructuredData::ObjectSP &implementor) override;
1435f29bb8aSDimitry Andric 
1445f29bb8aSDimitry Andric   lldb::ValueObjectSP
1455f29bb8aSDimitry Andric   GetSyntheticValue(const StructuredData::ObjectSP &implementor) override;
1465f29bb8aSDimitry Andric 
1475f29bb8aSDimitry Andric   ConstString
1485f29bb8aSDimitry Andric   GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override;
1495f29bb8aSDimitry Andric 
1505f29bb8aSDimitry Andric   bool
1515f29bb8aSDimitry Andric   RunScriptBasedCommand(const char *impl_function, llvm::StringRef args,
1525f29bb8aSDimitry Andric                         ScriptedCommandSynchronicity synchronicity,
1535f29bb8aSDimitry Andric                         lldb_private::CommandReturnObject &cmd_retobj,
1545f29bb8aSDimitry Andric                         Status &error,
1555f29bb8aSDimitry Andric                         const lldb_private::ExecutionContext &exe_ctx) override;
1565f29bb8aSDimitry Andric 
1575f29bb8aSDimitry Andric   bool RunScriptBasedCommand(
1585f29bb8aSDimitry Andric       StructuredData::GenericSP impl_obj_sp, llvm::StringRef args,
1595f29bb8aSDimitry Andric       ScriptedCommandSynchronicity synchronicity,
1605f29bb8aSDimitry Andric       lldb_private::CommandReturnObject &cmd_retobj, Status &error,
1615f29bb8aSDimitry Andric       const lldb_private::ExecutionContext &exe_ctx) override;
1625f29bb8aSDimitry Andric 
163ac9a064cSDimitry Andric   bool RunScriptBasedParsedCommand(
164ac9a064cSDimitry Andric       StructuredData::GenericSP impl_obj_sp, Args &args,
165ac9a064cSDimitry Andric       ScriptedCommandSynchronicity synchronicity,
166ac9a064cSDimitry Andric       lldb_private::CommandReturnObject &cmd_retobj, Status &error,
167ac9a064cSDimitry Andric       const lldb_private::ExecutionContext &exe_ctx) override;
168ac9a064cSDimitry Andric 
169ac9a064cSDimitry Andric   std::optional<std::string>
170ac9a064cSDimitry Andric   GetRepeatCommandForScriptedCommand(StructuredData::GenericSP impl_obj_sp,
171ac9a064cSDimitry Andric                                      Args &args) override;
172ac9a064cSDimitry Andric 
1737fa27ce4SDimitry Andric   Status GenerateFunction(const char *signature, const StringList &input,
1747fa27ce4SDimitry Andric                           bool is_callback) override;
1755f29bb8aSDimitry Andric 
1767fa27ce4SDimitry Andric   Status GenerateBreakpointCommandCallbackData(StringList &input,
177706b4fc4SDimitry Andric                                                std::string &output,
1787fa27ce4SDimitry Andric                                                bool has_extra_args,
1797fa27ce4SDimitry Andric                                                bool is_callback) override;
1805f29bb8aSDimitry Andric 
1815f29bb8aSDimitry Andric   bool GenerateWatchpointCommandCallbackData(StringList &input,
1827fa27ce4SDimitry Andric                                              std::string &output,
1837fa27ce4SDimitry Andric                                              bool is_callback) override;
1845f29bb8aSDimitry Andric 
1855f29bb8aSDimitry Andric   bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj,
1865f29bb8aSDimitry Andric                           StructuredData::ObjectSP &callee_wrapper_sp,
1875f29bb8aSDimitry Andric                           const TypeSummaryOptions &options,
1885f29bb8aSDimitry Andric                           std::string &retval) override;
1895f29bb8aSDimitry Andric 
190e3b55780SDimitry Andric   bool FormatterCallbackFunction(const char *function_name,
191e3b55780SDimitry Andric                                  lldb::TypeImplSP type_impl_sp) override;
192e3b55780SDimitry Andric 
1935f29bb8aSDimitry Andric   bool GetDocumentationForItem(const char *item, std::string &dest) override;
1945f29bb8aSDimitry Andric 
1955f29bb8aSDimitry Andric   bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
1965f29bb8aSDimitry Andric                                     std::string &dest) override;
1975f29bb8aSDimitry Andric 
1985f29bb8aSDimitry Andric   uint32_t
1995f29bb8aSDimitry Andric   GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override;
2005f29bb8aSDimitry Andric 
2015f29bb8aSDimitry Andric   bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
2025f29bb8aSDimitry Andric                                    std::string &dest) override;
2035f29bb8aSDimitry Andric 
204ac9a064cSDimitry Andric   StructuredData::ObjectSP
205ac9a064cSDimitry Andric   GetOptionsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override;
206ac9a064cSDimitry Andric 
207ac9a064cSDimitry Andric   StructuredData::ObjectSP
208ac9a064cSDimitry Andric   GetArgumentsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override;
209ac9a064cSDimitry Andric 
210ac9a064cSDimitry Andric   bool SetOptionValueForCommandObject(StructuredData::GenericSP cmd_obj_sp,
211ac9a064cSDimitry Andric                                       ExecutionContext *exe_ctx,
212ac9a064cSDimitry Andric                                       llvm::StringRef long_option,
213ac9a064cSDimitry Andric                                       llvm::StringRef value) override;
214ac9a064cSDimitry Andric 
215ac9a064cSDimitry Andric   void OptionParsingStartedForCommandObject(
216ac9a064cSDimitry Andric       StructuredData::GenericSP cmd_obj_sp) override;
217ac9a064cSDimitry Andric 
CheckObjectExists(const char * name)2185f29bb8aSDimitry Andric   bool CheckObjectExists(const char *name) override {
2195f29bb8aSDimitry Andric     if (!name || !name[0])
2205f29bb8aSDimitry Andric       return false;
2215f29bb8aSDimitry Andric     std::string temp;
2225f29bb8aSDimitry Andric     return GetDocumentationForItem(name, temp);
2235f29bb8aSDimitry Andric   }
2245f29bb8aSDimitry Andric 
2255f29bb8aSDimitry Andric   bool RunScriptFormatKeyword(const char *impl_function, Process *process,
2265f29bb8aSDimitry Andric                               std::string &output, Status &error) override;
2275f29bb8aSDimitry Andric 
2285f29bb8aSDimitry Andric   bool RunScriptFormatKeyword(const char *impl_function, Thread *thread,
2295f29bb8aSDimitry Andric                               std::string &output, Status &error) override;
2305f29bb8aSDimitry Andric 
2315f29bb8aSDimitry Andric   bool RunScriptFormatKeyword(const char *impl_function, Target *target,
2325f29bb8aSDimitry Andric                               std::string &output, Status &error) override;
2335f29bb8aSDimitry Andric 
2345f29bb8aSDimitry Andric   bool RunScriptFormatKeyword(const char *impl_function, StackFrame *frame,
2355f29bb8aSDimitry Andric                               std::string &output, Status &error) override;
2365f29bb8aSDimitry Andric 
2375f29bb8aSDimitry Andric   bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value,
2385f29bb8aSDimitry Andric                               std::string &output, Status &error) override;
2395f29bb8aSDimitry Andric 
240344a3780SDimitry Andric   bool LoadScriptingModule(const char *filename,
241344a3780SDimitry Andric                            const LoadScriptOptions &options,
2425f29bb8aSDimitry Andric                            lldb_private::Status &error,
243b60736ecSDimitry Andric                            StructuredData::ObjectSP *module_sp = nullptr,
244b60736ecSDimitry Andric                            FileSpec extra_search_dir = {}) override;
2455f29bb8aSDimitry Andric 
2465f29bb8aSDimitry Andric   bool IsReservedWord(const char *word) override;
2475f29bb8aSDimitry Andric 
2485f29bb8aSDimitry Andric   std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock() override;
2495f29bb8aSDimitry Andric 
2505f29bb8aSDimitry Andric   void CollectDataForBreakpointCommandCallback(
251344a3780SDimitry Andric       std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
2525f29bb8aSDimitry Andric       CommandReturnObject &result) override;
2535f29bb8aSDimitry Andric 
2545f29bb8aSDimitry Andric   void
2555f29bb8aSDimitry Andric   CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options,
2565f29bb8aSDimitry Andric                                           CommandReturnObject &result) override;
2575f29bb8aSDimitry Andric 
2585f29bb8aSDimitry Andric   /// Set the callback body text into the callback for the breakpoint.
259344a3780SDimitry Andric   Status SetBreakpointCommandCallback(BreakpointOptions &bp_options,
2607fa27ce4SDimitry Andric                                       const char *callback_body,
2617fa27ce4SDimitry Andric                                       bool is_callback) override;
2625f29bb8aSDimitry Andric 
263706b4fc4SDimitry Andric   Status SetBreakpointCommandCallbackFunction(
264344a3780SDimitry Andric       BreakpointOptions &bp_options, const char *function_name,
265706b4fc4SDimitry Andric       StructuredData::ObjectSP extra_args_sp) override;
2665f29bb8aSDimitry Andric 
2675f29bb8aSDimitry Andric   /// This one is for deserialization:
2685f29bb8aSDimitry Andric   Status SetBreakpointCommandCallback(
269344a3780SDimitry Andric       BreakpointOptions &bp_options,
2705f29bb8aSDimitry Andric       std::unique_ptr<BreakpointOptions::CommandData> &data_up) override;
2715f29bb8aSDimitry Andric 
272344a3780SDimitry Andric   Status SetBreakpointCommandCallback(BreakpointOptions &bp_options,
273706b4fc4SDimitry Andric                                       const char *command_body_text,
274706b4fc4SDimitry Andric                                       StructuredData::ObjectSP extra_args_sp,
2757fa27ce4SDimitry Andric                                       bool uses_extra_args,
2767fa27ce4SDimitry Andric                                       bool is_callback);
277706b4fc4SDimitry Andric 
2785f29bb8aSDimitry Andric   /// Set a one-liner as the callback for the watchpoint.
2795f29bb8aSDimitry Andric   void SetWatchpointCommandCallback(WatchpointOptions *wp_options,
2807fa27ce4SDimitry Andric                                     const char *user_input,
2817fa27ce4SDimitry Andric                                     bool is_callback) override;
2825f29bb8aSDimitry Andric 
GetDictionaryName()2835f29bb8aSDimitry Andric   const char *GetDictionaryName() { return m_dictionary_name.c_str(); }
2845f29bb8aSDimitry Andric 
GetThreadState()2855f29bb8aSDimitry Andric   PyThreadState *GetThreadState() { return m_command_thread_state; }
2865f29bb8aSDimitry Andric 
SetThreadState(PyThreadState * s)2875f29bb8aSDimitry Andric   void SetThreadState(PyThreadState *s) {
2885f29bb8aSDimitry Andric     if (s)
2895f29bb8aSDimitry Andric       m_command_thread_state = s;
2905f29bb8aSDimitry Andric   }
2915f29bb8aSDimitry Andric 
2925f29bb8aSDimitry Andric   // IOHandlerDelegate
2935f29bb8aSDimitry Andric   void IOHandlerActivated(IOHandler &io_handler, bool interactive) override;
2945f29bb8aSDimitry Andric 
2955f29bb8aSDimitry Andric   void IOHandlerInputComplete(IOHandler &io_handler,
2965f29bb8aSDimitry Andric                               std::string &data) override;
2975f29bb8aSDimitry Andric 
2985f29bb8aSDimitry Andric   static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger);
2995f29bb8aSDimitry Andric 
3005f29bb8aSDimitry Andric   // PluginInterface protocol
GetPluginName()301c0981da4SDimitry Andric   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
3025f29bb8aSDimitry Andric 
3035f29bb8aSDimitry Andric   class Locker : public ScriptInterpreterLocker {
3045f29bb8aSDimitry Andric   public:
3055f29bb8aSDimitry Andric     enum OnEntry {
3065f29bb8aSDimitry Andric       AcquireLock = 0x0001,
3075f29bb8aSDimitry Andric       InitSession = 0x0002,
3085f29bb8aSDimitry Andric       InitGlobals = 0x0004,
3095f29bb8aSDimitry Andric       NoSTDIN = 0x0008
3105f29bb8aSDimitry Andric     };
3115f29bb8aSDimitry Andric 
3125f29bb8aSDimitry Andric     enum OnLeave {
3135f29bb8aSDimitry Andric       FreeLock = 0x0001,
3145f29bb8aSDimitry Andric       FreeAcquiredLock = 0x0002, // do not free the lock if we already held it
3155f29bb8aSDimitry Andric                                  // when calling constructor
3165f29bb8aSDimitry Andric       TearDownSession = 0x0004
3175f29bb8aSDimitry Andric     };
3185f29bb8aSDimitry Andric 
319ead24645SDimitry Andric     Locker(ScriptInterpreterPythonImpl *py_interpreter,
3205f29bb8aSDimitry Andric            uint16_t on_entry = AcquireLock | InitSession,
321ead24645SDimitry Andric            uint16_t on_leave = FreeLock | TearDownSession,
322ead24645SDimitry Andric            lldb::FileSP in = nullptr, lldb::FileSP out = nullptr,
323ead24645SDimitry Andric            lldb::FileSP err = nullptr);
3245f29bb8aSDimitry Andric 
3255f29bb8aSDimitry Andric     ~Locker() override;
3265f29bb8aSDimitry Andric 
3275f29bb8aSDimitry Andric   private:
3285f29bb8aSDimitry Andric     bool DoAcquireLock();
3295f29bb8aSDimitry Andric 
330ead24645SDimitry Andric     bool DoInitSession(uint16_t on_entry_flags, lldb::FileSP in,
331ead24645SDimitry Andric                        lldb::FileSP out, lldb::FileSP err);
3325f29bb8aSDimitry Andric 
3335f29bb8aSDimitry Andric     bool DoFreeLock();
3345f29bb8aSDimitry Andric 
3355f29bb8aSDimitry Andric     bool DoTearDownSession();
3365f29bb8aSDimitry Andric 
3375f29bb8aSDimitry Andric     bool m_teardown_session;
3385f29bb8aSDimitry Andric     ScriptInterpreterPythonImpl *m_python_interpreter;
3395f29bb8aSDimitry Andric     PyGILState_STATE m_GILState;
3405f29bb8aSDimitry Andric   };
3415f29bb8aSDimitry Andric 
3425f29bb8aSDimitry Andric   static bool BreakpointCallbackFunction(void *baton,
3435f29bb8aSDimitry Andric                                          StoppointCallbackContext *context,
3445f29bb8aSDimitry Andric                                          lldb::user_id_t break_id,
3455f29bb8aSDimitry Andric                                          lldb::user_id_t break_loc_id);
3465f29bb8aSDimitry Andric   static bool WatchpointCallbackFunction(void *baton,
3475f29bb8aSDimitry Andric                                          StoppointCallbackContext *context,
3485f29bb8aSDimitry Andric                                          lldb::user_id_t watch_id);
3496f8fc217SDimitry Andric   static void Initialize();
3505f29bb8aSDimitry Andric 
3515f29bb8aSDimitry Andric   class SynchronicityHandler {
3525f29bb8aSDimitry Andric   private:
3535f29bb8aSDimitry Andric     lldb::DebuggerSP m_debugger_sp;
3545f29bb8aSDimitry Andric     ScriptedCommandSynchronicity m_synch_wanted;
3555f29bb8aSDimitry Andric     bool m_old_asynch;
3565f29bb8aSDimitry Andric 
3575f29bb8aSDimitry Andric   public:
3585f29bb8aSDimitry Andric     SynchronicityHandler(lldb::DebuggerSP, ScriptedCommandSynchronicity);
3595f29bb8aSDimitry Andric 
3605f29bb8aSDimitry Andric     ~SynchronicityHandler();
3615f29bb8aSDimitry Andric   };
3625f29bb8aSDimitry Andric 
3635f29bb8aSDimitry Andric   enum class AddLocation { Beginning, End };
3645f29bb8aSDimitry Andric 
3655f29bb8aSDimitry Andric   static void AddToSysPath(AddLocation location, std::string path);
3665f29bb8aSDimitry Andric 
367ead24645SDimitry Andric   bool EnterSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out,
368ead24645SDimitry Andric                     lldb::FileSP err);
3695f29bb8aSDimitry Andric 
3705f29bb8aSDimitry Andric   void LeaveSession();
3715f29bb8aSDimitry Andric 
IsExecutingPython()3727fa27ce4SDimitry Andric   uint32_t IsExecutingPython() {
3737fa27ce4SDimitry Andric     std::lock_guard<std::mutex> guard(m_mutex);
3747fa27ce4SDimitry Andric     return m_lock_count > 0;
3757fa27ce4SDimitry Andric   }
3765f29bb8aSDimitry Andric 
IncrementLockCount()3777fa27ce4SDimitry Andric   uint32_t IncrementLockCount() {
3787fa27ce4SDimitry Andric     std::lock_guard<std::mutex> guard(m_mutex);
3797fa27ce4SDimitry Andric     return ++m_lock_count;
3807fa27ce4SDimitry Andric   }
3815f29bb8aSDimitry Andric 
DecrementLockCount()3825f29bb8aSDimitry Andric   uint32_t DecrementLockCount() {
3837fa27ce4SDimitry Andric     std::lock_guard<std::mutex> guard(m_mutex);
3845f29bb8aSDimitry Andric     if (m_lock_count > 0)
3855f29bb8aSDimitry Andric       --m_lock_count;
3865f29bb8aSDimitry Andric     return m_lock_count;
3875f29bb8aSDimitry Andric   }
3885f29bb8aSDimitry Andric 
3895f29bb8aSDimitry Andric   enum ActiveIOHandler {
3905f29bb8aSDimitry Andric     eIOHandlerNone,
3915f29bb8aSDimitry Andric     eIOHandlerBreakpoint,
3925f29bb8aSDimitry Andric     eIOHandlerWatchpoint
3935f29bb8aSDimitry Andric   };
3945f29bb8aSDimitry Andric 
395ead24645SDimitry Andric   python::PythonModule &GetMainModule();
3965f29bb8aSDimitry Andric 
397ead24645SDimitry Andric   python::PythonDictionary &GetSessionDictionary();
3985f29bb8aSDimitry Andric 
399ead24645SDimitry Andric   python::PythonDictionary &GetSysModuleDictionary();
4005f29bb8aSDimitry Andric 
401706b4fc4SDimitry Andric   llvm::Expected<unsigned> GetMaxPositionalArgumentsForCallable(
402706b4fc4SDimitry Andric       const llvm::StringRef &callable_name) override;
403706b4fc4SDimitry Andric 
4045f29bb8aSDimitry Andric   bool GetEmbeddedInterpreterModuleObjects();
4055f29bb8aSDimitry Andric 
406ead24645SDimitry Andric   bool SetStdHandle(lldb::FileSP file, const char *py_name,
407ead24645SDimitry Andric                     python::PythonObject &save_file, const char *mode);
4085f29bb8aSDimitry Andric 
409ead24645SDimitry Andric   python::PythonObject m_saved_stdin;
410ead24645SDimitry Andric   python::PythonObject m_saved_stdout;
411ead24645SDimitry Andric   python::PythonObject m_saved_stderr;
412ead24645SDimitry Andric   python::PythonModule m_main_module;
413ead24645SDimitry Andric   python::PythonDictionary m_session_dict;
414ead24645SDimitry Andric   python::PythonDictionary m_sys_module_dict;
415ead24645SDimitry Andric   python::PythonObject m_run_one_line_function;
416ead24645SDimitry Andric   python::PythonObject m_run_one_line_str_global;
4175f29bb8aSDimitry Andric   std::string m_dictionary_name;
4185f29bb8aSDimitry Andric   ActiveIOHandler m_active_io_handler;
4195f29bb8aSDimitry Andric   bool m_session_is_active;
420cfca06d7SDimitry Andric   bool m_pty_secondary_is_open;
4215f29bb8aSDimitry Andric   bool m_valid_session;
4225f29bb8aSDimitry Andric   uint32_t m_lock_count;
4237fa27ce4SDimitry Andric   std::mutex m_mutex;
4245f29bb8aSDimitry Andric   PyThreadState *m_command_thread_state;
4255f29bb8aSDimitry Andric };
4265f29bb8aSDimitry Andric 
4275f29bb8aSDimitry Andric class IOHandlerPythonInterpreter : public IOHandler {
4285f29bb8aSDimitry Andric public:
IOHandlerPythonInterpreter(Debugger & debugger,ScriptInterpreterPythonImpl * python)4295f29bb8aSDimitry Andric   IOHandlerPythonInterpreter(Debugger &debugger,
4305f29bb8aSDimitry Andric                              ScriptInterpreterPythonImpl *python)
4315f29bb8aSDimitry Andric       : IOHandler(debugger, IOHandler::Type::PythonInterpreter),
4325f29bb8aSDimitry Andric         m_python(python) {}
4335f29bb8aSDimitry Andric 
434344a3780SDimitry Andric   ~IOHandlerPythonInterpreter() override = default;
4355f29bb8aSDimitry Andric 
GetControlSequence(char ch)4367fa27ce4SDimitry Andric   llvm::StringRef GetControlSequence(char ch) override {
4377fa27ce4SDimitry Andric     static constexpr llvm::StringLiteral control_sequence("quit()\n");
4385f29bb8aSDimitry Andric     if (ch == 'd')
4397fa27ce4SDimitry Andric       return control_sequence;
4407fa27ce4SDimitry Andric     return {};
4415f29bb8aSDimitry Andric   }
4425f29bb8aSDimitry Andric 
Run()4435f29bb8aSDimitry Andric   void Run() override {
4445f29bb8aSDimitry Andric     if (m_python) {
4455f29bb8aSDimitry Andric       int stdin_fd = GetInputFD();
4465f29bb8aSDimitry Andric       if (stdin_fd >= 0) {
4475f29bb8aSDimitry Andric         Terminal terminal(stdin_fd);
448c0981da4SDimitry Andric         TerminalState terminal_state(terminal);
4495f29bb8aSDimitry Andric 
450c0981da4SDimitry Andric         if (terminal.IsATerminal()) {
451c0981da4SDimitry Andric           // FIXME: error handling?
452c0981da4SDimitry Andric           llvm::consumeError(terminal.SetCanonical(false));
453c0981da4SDimitry Andric           llvm::consumeError(terminal.SetEcho(true));
4545f29bb8aSDimitry Andric         }
4555f29bb8aSDimitry Andric 
4565f29bb8aSDimitry Andric         ScriptInterpreterPythonImpl::Locker locker(
4575f29bb8aSDimitry Andric             m_python,
4585f29bb8aSDimitry Andric             ScriptInterpreterPythonImpl::Locker::AcquireLock |
4595f29bb8aSDimitry Andric                 ScriptInterpreterPythonImpl::Locker::InitSession |
4605f29bb8aSDimitry Andric                 ScriptInterpreterPythonImpl::Locker::InitGlobals,
4615f29bb8aSDimitry Andric             ScriptInterpreterPythonImpl::Locker::FreeAcquiredLock |
4625f29bb8aSDimitry Andric                 ScriptInterpreterPythonImpl::Locker::TearDownSession);
4635f29bb8aSDimitry Andric 
4645f29bb8aSDimitry Andric         // The following call drops into the embedded interpreter loop and
4655f29bb8aSDimitry Andric         // stays there until the user chooses to exit from the Python
4665f29bb8aSDimitry Andric         // interpreter. This embedded interpreter will, as any Python code that
4675f29bb8aSDimitry Andric         // performs I/O, unlock the GIL before a system call that can hang, and
4685f29bb8aSDimitry Andric         // lock it when the syscall has returned.
4695f29bb8aSDimitry Andric 
4705f29bb8aSDimitry Andric         // We need to surround the call to the embedded interpreter with calls
4715f29bb8aSDimitry Andric         // to PyGILState_Ensure and PyGILState_Release (using the Locker
4725f29bb8aSDimitry Andric         // above). This is because Python has a global lock which must be held
4735f29bb8aSDimitry Andric         // whenever we want to touch any Python objects. Otherwise, if the user
4745f29bb8aSDimitry Andric         // calls Python code, the interpreter state will be off, and things
4755f29bb8aSDimitry Andric         // could hang (it's happened before).
4765f29bb8aSDimitry Andric 
4775f29bb8aSDimitry Andric         StreamString run_string;
4785f29bb8aSDimitry Andric         run_string.Printf("run_python_interpreter (%s)",
4795f29bb8aSDimitry Andric                           m_python->GetDictionaryName());
4805f29bb8aSDimitry Andric         PyRun_SimpleString(run_string.GetData());
4815f29bb8aSDimitry Andric       }
4825f29bb8aSDimitry Andric     }
4835f29bb8aSDimitry Andric     SetIsDone(true);
4845f29bb8aSDimitry Andric   }
4855f29bb8aSDimitry Andric 
Cancel()4865f29bb8aSDimitry Andric   void Cancel() override {}
4875f29bb8aSDimitry Andric 
Interrupt()4885f29bb8aSDimitry Andric   bool Interrupt() override { return m_python->Interrupt(); }
4895f29bb8aSDimitry Andric 
GotEOF()4905f29bb8aSDimitry Andric   void GotEOF() override {}
4915f29bb8aSDimitry Andric 
4925f29bb8aSDimitry Andric protected:
4935f29bb8aSDimitry Andric   ScriptInterpreterPythonImpl *m_python;
4945f29bb8aSDimitry Andric };
4955f29bb8aSDimitry Andric 
4965f29bb8aSDimitry Andric } // namespace lldb_private
4975f29bb8aSDimitry Andric 
498344a3780SDimitry Andric #endif // LLDB_ENABLE_PYTHON
499344a3780SDimitry Andric #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H
500