19f2f44ceSEd Maste //===-- ScriptInterpreterPython.cpp -----------------------------*- C++ -*-===//
29f2f44ceSEd Maste //
39f2f44ceSEd Maste //                     The LLVM Compiler Infrastructure
49f2f44ceSEd Maste //
59f2f44ceSEd Maste // This file is distributed under the University of Illinois Open Source
69f2f44ceSEd Maste // License. See LICENSE.TXT for details.
79f2f44ceSEd Maste //
89f2f44ceSEd Maste //===----------------------------------------------------------------------===//
99f2f44ceSEd Maste 
109f2f44ceSEd Maste #ifdef LLDB_DISABLE_PYTHON
119f2f44ceSEd Maste 
129f2f44ceSEd Maste // Python is disabled in this build
139f2f44ceSEd Maste 
149f2f44ceSEd Maste #else
159f2f44ceSEd Maste 
16435933ddSDimitry Andric // LLDB Python header must be included first
179f2f44ceSEd Maste #include "lldb-python.h"
18435933ddSDimitry Andric 
199f2f44ceSEd Maste #include "PythonDataObjects.h"
209f2f44ceSEd Maste #include "PythonExceptionState.h"
21435933ddSDimitry Andric #include "ScriptInterpreterPython.h"
229f2f44ceSEd Maste 
239f2f44ceSEd Maste #include <stdio.h>
24435933ddSDimitry Andric #include <stdlib.h>
259f2f44ceSEd Maste 
269f2f44ceSEd Maste #include <mutex>
279f2f44ceSEd Maste #include <string>
289f2f44ceSEd Maste 
299f2f44ceSEd Maste #include "lldb/API/SBValue.h"
30*b5893f02SDimitry Andric #include "lldb/API/SBFrame.h"
319f2f44ceSEd Maste #include "lldb/Breakpoint/BreakpointLocation.h"
329f2f44ceSEd Maste #include "lldb/Breakpoint/StoppointCallbackContext.h"
339f2f44ceSEd Maste #include "lldb/Breakpoint/WatchpointOptions.h"
349f2f44ceSEd Maste #include "lldb/Core/Communication.h"
359f2f44ceSEd Maste #include "lldb/Core/Debugger.h"
369f2f44ceSEd Maste #include "lldb/Core/PluginManager.h"
379f2f44ceSEd Maste #include "lldb/Core/ValueObject.h"
389f2f44ceSEd Maste #include "lldb/DataFormatters/TypeSummary.h"
399f2f44ceSEd Maste #include "lldb/Host/ConnectionFileDescriptor.h"
409f2f44ceSEd Maste #include "lldb/Host/FileSystem.h"
419f2f44ceSEd Maste #include "lldb/Host/HostInfo.h"
429f2f44ceSEd Maste #include "lldb/Host/Pipe.h"
439f2f44ceSEd Maste #include "lldb/Interpreter/CommandInterpreter.h"
449f2f44ceSEd Maste #include "lldb/Interpreter/CommandReturnObject.h"
459f2f44ceSEd Maste #include "lldb/Target/Thread.h"
469f2f44ceSEd Maste #include "lldb/Target/ThreadPlan.h"
47a580b014SDimitry Andric #include "lldb/Utility/Timer.h"
489f2f44ceSEd Maste 
499f2f44ceSEd Maste #if defined(_WIN32)
509f2f44ceSEd Maste #include "lldb/Host/windows/ConnectionGenericFileWindows.h"
519f2f44ceSEd Maste #endif
529f2f44ceSEd Maste 
539f2f44ceSEd Maste #include "llvm/ADT/STLExtras.h"
54435933ddSDimitry Andric #include "llvm/ADT/StringRef.h"
55f678e45dSDimitry Andric #include "llvm/Support/FileSystem.h"
569f2f44ceSEd Maste 
579f2f44ceSEd Maste using namespace lldb;
589f2f44ceSEd Maste using namespace lldb_private;
599f2f44ceSEd Maste 
609f2f44ceSEd Maste static ScriptInterpreterPython::SWIGInitCallback g_swig_init_callback = nullptr;
61435933ddSDimitry Andric static ScriptInterpreterPython::SWIGBreakpointCallbackFunction
62435933ddSDimitry Andric     g_swig_breakpoint_callback = nullptr;
63435933ddSDimitry Andric static ScriptInterpreterPython::SWIGWatchpointCallbackFunction
64435933ddSDimitry Andric     g_swig_watchpoint_callback = nullptr;
65435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonTypeScriptCallbackFunction
66435933ddSDimitry Andric     g_swig_typescript_callback = nullptr;
67435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonCreateSyntheticProvider
68435933ddSDimitry Andric     g_swig_synthetic_script = nullptr;
69435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonCreateCommandObject
70435933ddSDimitry Andric     g_swig_create_cmd = nullptr;
71435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonCalculateNumChildren
72435933ddSDimitry Andric     g_swig_calc_children = nullptr;
73435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonGetChildAtIndex
74435933ddSDimitry Andric     g_swig_get_child_index = nullptr;
75435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonGetIndexOfChildWithName
76435933ddSDimitry Andric     g_swig_get_index_child = nullptr;
77435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonCastPyObjectToSBValue
78435933ddSDimitry Andric     g_swig_cast_to_sbvalue = nullptr;
79435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonGetValueObjectSPFromSBValue
80435933ddSDimitry Andric     g_swig_get_valobj_sp_from_sbvalue = nullptr;
81435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonUpdateSynthProviderInstance
82435933ddSDimitry Andric     g_swig_update_provider = nullptr;
83435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonMightHaveChildrenSynthProviderInstance
84435933ddSDimitry Andric     g_swig_mighthavechildren_provider = nullptr;
85435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonGetValueSynthProviderInstance
86435933ddSDimitry Andric     g_swig_getvalue_provider = nullptr;
87435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonCallCommand g_swig_call_command =
88435933ddSDimitry Andric     nullptr;
89435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonCallCommandObject
90435933ddSDimitry Andric     g_swig_call_command_object = nullptr;
91435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonCallModuleInit
92435933ddSDimitry Andric     g_swig_call_module_init = nullptr;
93435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonCreateOSPlugin
94435933ddSDimitry Andric     g_swig_create_os_plugin = nullptr;
95*b5893f02SDimitry Andric static ScriptInterpreterPython::SWIGPythonCreateFrameRecognizer
96*b5893f02SDimitry Andric     g_swig_create_frame_recognizer = nullptr;
97*b5893f02SDimitry Andric static ScriptInterpreterPython::SWIGPythonGetRecognizedArguments
98*b5893f02SDimitry Andric     g_swig_get_recognized_arguments = nullptr;
99435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonScriptKeyword_Process
100435933ddSDimitry Andric     g_swig_run_script_keyword_process = nullptr;
101435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonScriptKeyword_Thread
102435933ddSDimitry Andric     g_swig_run_script_keyword_thread = nullptr;
103435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonScriptKeyword_Target
104435933ddSDimitry Andric     g_swig_run_script_keyword_target = nullptr;
105435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonScriptKeyword_Frame
106435933ddSDimitry Andric     g_swig_run_script_keyword_frame = nullptr;
107435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonScriptKeyword_Value
108435933ddSDimitry Andric     g_swig_run_script_keyword_value = nullptr;
109435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPython_GetDynamicSetting g_swig_plugin_get =
110435933ddSDimitry Andric     nullptr;
111435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonCreateScriptedThreadPlan
112435933ddSDimitry Andric     g_swig_thread_plan_script = nullptr;
113435933ddSDimitry Andric static ScriptInterpreterPython::SWIGPythonCallThreadPlan
114435933ddSDimitry Andric     g_swig_call_thread_plan = nullptr;
115*b5893f02SDimitry Andric static ScriptInterpreterPython::SWIGPythonCreateScriptedBreakpointResolver
116*b5893f02SDimitry Andric     g_swig_bkpt_resolver_script = nullptr;
117*b5893f02SDimitry Andric static ScriptInterpreterPython::SWIGPythonCallBreakpointResolver
118*b5893f02SDimitry Andric     g_swig_call_bkpt_resolver = nullptr;
1199f2f44ceSEd Maste 
1209f2f44ceSEd Maste static bool g_initialized = false;
1219f2f44ceSEd Maste 
122435933ddSDimitry Andric namespace {
1239f2f44ceSEd Maste 
1244ba319b5SDimitry Andric // Initializing Python is not a straightforward process.  We cannot control
1254ba319b5SDimitry Andric // what external code may have done before getting to this point in LLDB,
1264ba319b5SDimitry Andric // including potentially having already initialized Python, so we need to do a
1274ba319b5SDimitry Andric // lot of work to ensure that the existing state of the system is maintained
1284ba319b5SDimitry Andric // across our initialization.  We do this by using an RAII pattern where we
1294ba319b5SDimitry Andric // save off initial state at the beginning, and restore it at the end
130435933ddSDimitry Andric struct InitializePythonRAII {
1319f2f44ceSEd Maste public:
InitializePythonRAII__anon438f0be10111::InitializePythonRAII132435933ddSDimitry Andric   InitializePythonRAII()
133435933ddSDimitry Andric       : m_gil_state(PyGILState_UNLOCKED), m_was_already_initialized(false) {
1349f2f44ceSEd Maste     // Python will muck with STDIN terminal state, so save off any current TTY
1359f2f44ceSEd Maste     // settings so we can restore them.
1369f2f44ceSEd Maste     m_stdin_tty_state.Save(STDIN_FILENO, false);
1379f2f44ceSEd Maste 
1389f2f44ceSEd Maste     InitializePythonHome();
1399f2f44ceSEd Maste 
140*b5893f02SDimitry Andric     // Register _lldb as a built-in module.
141*b5893f02SDimitry Andric     PyImport_AppendInittab("_lldb", g_swig_init_callback);
142*b5893f02SDimitry Andric 
1439f2f44ceSEd Maste // Python < 3.2 and Python >= 3.2 reversed the ordering requirements for
1449f2f44ceSEd Maste // calling `Py_Initialize` and `PyEval_InitThreads`.  < 3.2 requires that you
1459f2f44ceSEd Maste // call `PyEval_InitThreads` first, and >= 3.2 requires that you call it last.
1469f2f44ceSEd Maste #if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 2) || (PY_MAJOR_VERSION > 3)
1479f2f44ceSEd Maste     Py_InitializeEx(0);
1489f2f44ceSEd Maste     InitializeThreadsPrivate();
1499f2f44ceSEd Maste #else
1509f2f44ceSEd Maste     InitializeThreadsPrivate();
1519f2f44ceSEd Maste     Py_InitializeEx(0);
1529f2f44ceSEd Maste #endif
1539f2f44ceSEd Maste   }
1549f2f44ceSEd Maste 
~InitializePythonRAII__anon438f0be10111::InitializePythonRAII155435933ddSDimitry Andric   ~InitializePythonRAII() {
156435933ddSDimitry Andric     if (m_was_already_initialized) {
157f678e45dSDimitry Andric       Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
158f678e45dSDimitry Andric       LLDB_LOGV(log, "Releasing PyGILState. Returning to state = {0}locked",
159f678e45dSDimitry Andric                 m_was_already_initialized == PyGILState_UNLOCKED ? "un" : "");
1609f2f44ceSEd Maste       PyGILState_Release(m_gil_state);
161435933ddSDimitry Andric     } else {
1629f2f44ceSEd Maste       // We initialized the threads in this function, just unlock the GIL.
1639f2f44ceSEd Maste       PyEval_SaveThread();
1649f2f44ceSEd Maste     }
1659f2f44ceSEd Maste 
1669f2f44ceSEd Maste     m_stdin_tty_state.Restore();
1679f2f44ceSEd Maste   }
1689f2f44ceSEd Maste 
1699f2f44ceSEd Maste private:
InitializePythonHome__anon438f0be10111::InitializePythonRAII170435933ddSDimitry Andric   void InitializePythonHome() {
1719f2f44ceSEd Maste #if defined(LLDB_PYTHON_HOME)
1729f2f44ceSEd Maste #if PY_MAJOR_VERSION >= 3
1739f2f44ceSEd Maste     size_t size = 0;
1749f2f44ceSEd Maste     static wchar_t *g_python_home = Py_DecodeLocale(LLDB_PYTHON_HOME, &size);
1759f2f44ceSEd Maste #else
1764bb0738eSEd Maste     static char g_python_home[] = LLDB_PYTHON_HOME;
1779f2f44ceSEd Maste #endif
1789f2f44ceSEd Maste     Py_SetPythonHome(g_python_home);
1799f2f44ceSEd Maste #endif
1809f2f44ceSEd Maste   }
1819f2f44ceSEd Maste 
InitializeThreadsPrivate__anon438f0be10111::InitializePythonRAII182435933ddSDimitry Andric   void InitializeThreadsPrivate() {
183435933ddSDimitry Andric     if (PyEval_ThreadsInitialized()) {
184f678e45dSDimitry Andric       Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
1859f2f44ceSEd Maste 
1869f2f44ceSEd Maste       m_was_already_initialized = true;
1879f2f44ceSEd Maste       m_gil_state = PyGILState_Ensure();
188f678e45dSDimitry Andric       LLDB_LOGV(log, "Ensured PyGILState. Previous state = {0}locked\n",
1899f2f44ceSEd Maste                 m_gil_state == PyGILState_UNLOCKED ? "un" : "");
1909f2f44ceSEd Maste       return;
1919f2f44ceSEd Maste     }
1929f2f44ceSEd Maste 
1939f2f44ceSEd Maste     // InitThreads acquires the GIL if it hasn't been called before.
1949f2f44ceSEd Maste     PyEval_InitThreads();
1959f2f44ceSEd Maste   }
1969f2f44ceSEd Maste 
1979f2f44ceSEd Maste   TerminalState m_stdin_tty_state;
1989f2f44ceSEd Maste   PyGILState_STATE m_gil_state;
1999f2f44ceSEd Maste   bool m_was_already_initialized;
2009f2f44ceSEd Maste };
2019f2f44ceSEd Maste }
2029f2f44ceSEd Maste 
Locker(ScriptInterpreterPython * py_interpreter,uint16_t on_entry,uint16_t on_leave,FILE * in,FILE * out,FILE * err)2039f2f44ceSEd Maste ScriptInterpreterPython::Locker::Locker(ScriptInterpreterPython *py_interpreter,
204435933ddSDimitry Andric                                         uint16_t on_entry, uint16_t on_leave,
205435933ddSDimitry Andric                                         FILE *in, FILE *out, FILE *err)
206435933ddSDimitry Andric     : ScriptInterpreterLocker(),
2079f2f44ceSEd Maste       m_teardown_session((on_leave & TearDownSession) == TearDownSession),
208435933ddSDimitry Andric       m_python_interpreter(py_interpreter) {
2099f2f44ceSEd Maste   DoAcquireLock();
210435933ddSDimitry Andric   if ((on_entry & InitSession) == InitSession) {
211*b5893f02SDimitry Andric     if (!DoInitSession(on_entry, in, out, err)) {
2129f2f44ceSEd Maste       // Don't teardown the session if we didn't init it.
2139f2f44ceSEd Maste       m_teardown_session = false;
2149f2f44ceSEd Maste     }
2159f2f44ceSEd Maste   }
2169f2f44ceSEd Maste }
2179f2f44ceSEd Maste 
DoAcquireLock()218435933ddSDimitry Andric bool ScriptInterpreterPython::Locker::DoAcquireLock() {
219f678e45dSDimitry Andric   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
2209f2f44ceSEd Maste   m_GILState = PyGILState_Ensure();
221f678e45dSDimitry Andric   LLDB_LOGV(log, "Ensured PyGILState. Previous state = {0}locked",
222435933ddSDimitry Andric             m_GILState == PyGILState_UNLOCKED ? "un" : "");
2239f2f44ceSEd Maste 
2244ba319b5SDimitry Andric   // we need to save the thread state when we first start the command because
2254ba319b5SDimitry Andric   // we might decide to interrupt it while some action is taking place outside
2264ba319b5SDimitry Andric   // of Python (e.g. printing to screen, waiting for the network, ...) in that
2274ba319b5SDimitry Andric   // case, _PyThreadState_Current will be NULL - and we would be unable to set
2284ba319b5SDimitry Andric   // the asynchronous exception - not a desirable situation
2299f2f44ceSEd Maste   m_python_interpreter->SetThreadState(PyThreadState_Get());
2309f2f44ceSEd Maste   m_python_interpreter->IncrementLockCount();
2319f2f44ceSEd Maste   return true;
2329f2f44ceSEd Maste }
2339f2f44ceSEd Maste 
DoInitSession(uint16_t on_entry_flags,FILE * in,FILE * out,FILE * err)234435933ddSDimitry Andric bool ScriptInterpreterPython::Locker::DoInitSession(uint16_t on_entry_flags,
235435933ddSDimitry Andric                                                     FILE *in, FILE *out,
236435933ddSDimitry Andric                                                     FILE *err) {
2379f2f44ceSEd Maste   if (!m_python_interpreter)
2389f2f44ceSEd Maste     return false;
2399f2f44ceSEd Maste   return m_python_interpreter->EnterSession(on_entry_flags, in, out, err);
2409f2f44ceSEd Maste }
2419f2f44ceSEd Maste 
DoFreeLock()242435933ddSDimitry Andric bool ScriptInterpreterPython::Locker::DoFreeLock() {
243f678e45dSDimitry Andric   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
244f678e45dSDimitry Andric   LLDB_LOGV(log, "Releasing PyGILState. Returning to state = {0}locked",
245435933ddSDimitry Andric             m_GILState == PyGILState_UNLOCKED ? "un" : "");
2469f2f44ceSEd Maste   PyGILState_Release(m_GILState);
2479f2f44ceSEd Maste   m_python_interpreter->DecrementLockCount();
2489f2f44ceSEd Maste   return true;
2499f2f44ceSEd Maste }
2509f2f44ceSEd Maste 
DoTearDownSession()251435933ddSDimitry Andric bool ScriptInterpreterPython::Locker::DoTearDownSession() {
2529f2f44ceSEd Maste   if (!m_python_interpreter)
2539f2f44ceSEd Maste     return false;
2549f2f44ceSEd Maste   m_python_interpreter->LeaveSession();
2559f2f44ceSEd Maste   return true;
2569f2f44ceSEd Maste }
2579f2f44ceSEd Maste 
~Locker()258435933ddSDimitry Andric ScriptInterpreterPython::Locker::~Locker() {
2599f2f44ceSEd Maste   if (m_teardown_session)
2609f2f44ceSEd Maste     DoTearDownSession();
2619f2f44ceSEd Maste   DoFreeLock();
2629f2f44ceSEd Maste }
2639f2f44ceSEd Maste 
ScriptInterpreterPython(CommandInterpreter & interpreter)264435933ddSDimitry Andric ScriptInterpreterPython::ScriptInterpreterPython(
265435933ddSDimitry Andric     CommandInterpreter &interpreter)
266435933ddSDimitry Andric     : ScriptInterpreter(interpreter, eScriptLanguagePython),
267435933ddSDimitry Andric       IOHandlerDelegateMultiline("DONE"), m_saved_stdin(), m_saved_stdout(),
268435933ddSDimitry Andric       m_saved_stderr(), m_main_module(), m_lldb_module(),
2699f2f44ceSEd Maste       m_session_dict(PyInitialValue::Invalid),
270435933ddSDimitry Andric       m_sys_module_dict(PyInitialValue::Invalid), m_run_one_line_function(),
2719f2f44ceSEd Maste       m_run_one_line_str_global(),
272435933ddSDimitry Andric       m_dictionary_name(
273435933ddSDimitry Andric           interpreter.GetDebugger().GetInstanceName().AsCString()),
274435933ddSDimitry Andric       m_terminal_state(), m_active_io_handler(eIOHandlerNone),
275435933ddSDimitry Andric       m_session_is_active(false), m_pty_slave_is_open(false),
276435933ddSDimitry Andric       m_valid_session(true), m_lock_count(0), m_command_thread_state(nullptr) {
2774bb0738eSEd Maste   InitializePrivate();
2789f2f44ceSEd Maste 
2799f2f44ceSEd Maste   m_dictionary_name.append("_dict");
2809f2f44ceSEd Maste   StreamString run_string;
2819f2f44ceSEd Maste   run_string.Printf("%s = dict()", m_dictionary_name.c_str());
2829f2f44ceSEd Maste 
283435933ddSDimitry Andric   Locker locker(this, ScriptInterpreterPython::Locker::AcquireLock,
2849f2f44ceSEd Maste                 ScriptInterpreterPython::Locker::FreeAcquiredLock);
2859f2f44ceSEd Maste   PyRun_SimpleString(run_string.GetData());
2869f2f44ceSEd Maste 
2879f2f44ceSEd Maste   run_string.Clear();
288435933ddSDimitry Andric   run_string.Printf(
289435933ddSDimitry Andric       "run_one_line (%s, 'import copy, keyword, os, re, sys, uuid, lldb')",
290435933ddSDimitry Andric       m_dictionary_name.c_str());
2919f2f44ceSEd Maste   PyRun_SimpleString(run_string.GetData());
2929f2f44ceSEd Maste 
293435933ddSDimitry Andric   // Reloading modules requires a different syntax in Python 2 and Python 3.
2944ba319b5SDimitry Andric   // This provides a consistent syntax no matter what version of Python.
2959f2f44ceSEd Maste   run_string.Clear();
296435933ddSDimitry Andric   run_string.Printf("run_one_line (%s, 'from six.moves import reload_module')",
297435933ddSDimitry Andric                     m_dictionary_name.c_str());
2989f2f44ceSEd Maste   PyRun_SimpleString(run_string.GetData());
2999f2f44ceSEd Maste 
300435933ddSDimitry Andric   // WARNING: temporary code that loads Cocoa formatters - this should be done
3014ba319b5SDimitry Andric   // on a per-platform basis rather than loading the whole set and letting the
3024ba319b5SDimitry Andric   // individual formatter classes exploit APIs to check whether they can/cannot
3034ba319b5SDimitry Andric   // do their task
3049f2f44ceSEd Maste   run_string.Clear();
305435933ddSDimitry Andric   run_string.Printf(
306435933ddSDimitry Andric       "run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp, pydoc')",
307435933ddSDimitry Andric       m_dictionary_name.c_str());
3089f2f44ceSEd Maste   PyRun_SimpleString(run_string.GetData());
3099f2f44ceSEd Maste   run_string.Clear();
3109f2f44ceSEd Maste 
311435933ddSDimitry Andric   run_string.Printf("run_one_line (%s, 'import lldb.embedded_interpreter; from "
312435933ddSDimitry Andric                     "lldb.embedded_interpreter import run_python_interpreter; "
313435933ddSDimitry Andric                     "from lldb.embedded_interpreter import run_one_line')",
314435933ddSDimitry Andric                     m_dictionary_name.c_str());
3159f2f44ceSEd Maste   PyRun_SimpleString(run_string.GetData());
3169f2f44ceSEd Maste   run_string.Clear();
3179f2f44ceSEd Maste 
318435933ddSDimitry Andric   run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64
319435933ddSDimitry Andric                     "; pydoc.pager = pydoc.plainpager')",
320435933ddSDimitry Andric                     m_dictionary_name.c_str(),
3219f2f44ceSEd Maste                     interpreter.GetDebugger().GetID());
3229f2f44ceSEd Maste   PyRun_SimpleString(run_string.GetData());
3239f2f44ceSEd Maste }
3249f2f44ceSEd Maste 
~ScriptInterpreterPython()325435933ddSDimitry Andric ScriptInterpreterPython::~ScriptInterpreterPython() {
3264ba319b5SDimitry Andric   // the session dictionary may hold objects with complex state which means
3274ba319b5SDimitry Andric   // that they may need to be torn down with some level of smarts and that, in
3284ba319b5SDimitry Andric   // turn, requires a valid thread state force Python to procure itself such a
3294ba319b5SDimitry Andric   // thread state, nuke the session dictionary and then release it for others
3304ba319b5SDimitry Andric   // to use and proceed with the rest of the shutdown
3319f2f44ceSEd Maste   auto gil_state = PyGILState_Ensure();
3329f2f44ceSEd Maste   m_session_dict.Reset();
3339f2f44ceSEd Maste   PyGILState_Release(gil_state);
3349f2f44ceSEd Maste }
3359f2f44ceSEd Maste 
Initialize()336435933ddSDimitry Andric void ScriptInterpreterPython::Initialize() {
337f678e45dSDimitry Andric   static llvm::once_flag g_once_flag;
3389f2f44ceSEd Maste 
339f678e45dSDimitry Andric   llvm::call_once(g_once_flag, []() {
3409f2f44ceSEd Maste     PluginManager::RegisterPlugin(GetPluginNameStatic(),
3419f2f44ceSEd Maste                                   GetPluginDescriptionStatic(),
342435933ddSDimitry Andric                                   lldb::eScriptLanguagePython, CreateInstance);
3439f2f44ceSEd Maste   });
3449f2f44ceSEd Maste }
3459f2f44ceSEd Maste 
Terminate()346435933ddSDimitry Andric void ScriptInterpreterPython::Terminate() {}
3479f2f44ceSEd Maste 
3489f2f44ceSEd Maste lldb::ScriptInterpreterSP
CreateInstance(CommandInterpreter & interpreter)349435933ddSDimitry Andric ScriptInterpreterPython::CreateInstance(CommandInterpreter &interpreter) {
3509f2f44ceSEd Maste   return std::make_shared<ScriptInterpreterPython>(interpreter);
3519f2f44ceSEd Maste }
3529f2f44ceSEd Maste 
GetPluginNameStatic()353435933ddSDimitry Andric lldb_private::ConstString ScriptInterpreterPython::GetPluginNameStatic() {
3549f2f44ceSEd Maste   static ConstString g_name("script-python");
3559f2f44ceSEd Maste   return g_name;
3569f2f44ceSEd Maste }
3579f2f44ceSEd Maste 
GetPluginDescriptionStatic()358435933ddSDimitry Andric const char *ScriptInterpreterPython::GetPluginDescriptionStatic() {
3599f2f44ceSEd Maste   return "Embedded Python interpreter";
3609f2f44ceSEd Maste }
3619f2f44ceSEd Maste 
ComputePythonDirForApple(llvm::SmallVectorImpl<char> & path)3624ba319b5SDimitry Andric void ScriptInterpreterPython::ComputePythonDirForApple(
3634ba319b5SDimitry Andric     llvm::SmallVectorImpl<char> &path) {
3644ba319b5SDimitry Andric   auto style = llvm::sys::path::Style::posix;
3654ba319b5SDimitry Andric 
3664ba319b5SDimitry Andric   llvm::StringRef path_ref(path.begin(), path.size());
3674ba319b5SDimitry Andric   auto rbegin = llvm::sys::path::rbegin(path_ref, style);
3684ba319b5SDimitry Andric   auto rend = llvm::sys::path::rend(path_ref);
3694ba319b5SDimitry Andric   auto framework = std::find(rbegin, rend, "LLDB.framework");
3704ba319b5SDimitry Andric   if (framework == rend) {
3714ba319b5SDimitry Andric     ComputePythonDirForPosix(path);
3724ba319b5SDimitry Andric     return;
3734ba319b5SDimitry Andric   }
3744ba319b5SDimitry Andric   path.resize(framework - rend);
3754ba319b5SDimitry Andric   llvm::sys::path::append(path, style, "LLDB.framework", "Resources", "Python");
3764ba319b5SDimitry Andric }
3774ba319b5SDimitry Andric 
ComputePythonDirForPosix(llvm::SmallVectorImpl<char> & path)3784ba319b5SDimitry Andric void ScriptInterpreterPython::ComputePythonDirForPosix(
3794ba319b5SDimitry Andric     llvm::SmallVectorImpl<char> &path) {
3804ba319b5SDimitry Andric   auto style = llvm::sys::path::Style::posix;
3814ba319b5SDimitry Andric #if defined(LLDB_PYTHON_RELATIVE_LIBDIR)
3824ba319b5SDimitry Andric   // Build the path by backing out of the lib dir, then building with whatever
3834ba319b5SDimitry Andric   // the real python interpreter uses.  (e.g. lib for most, lib64 on RHEL
3844ba319b5SDimitry Andric   // x86_64).
3854ba319b5SDimitry Andric   llvm::sys::path::remove_filename(path, style);
3864ba319b5SDimitry Andric   llvm::sys::path::append(path, style, LLDB_PYTHON_RELATIVE_LIBDIR);
3874ba319b5SDimitry Andric #else
3884ba319b5SDimitry Andric   llvm::sys::path::append(path, style,
3894ba319b5SDimitry Andric                           "python" + llvm::Twine(PY_MAJOR_VERSION) + "." +
3904ba319b5SDimitry Andric                               llvm::Twine(PY_MINOR_VERSION),
3914ba319b5SDimitry Andric                           "site-packages");
3924ba319b5SDimitry Andric #endif
3934ba319b5SDimitry Andric }
3944ba319b5SDimitry Andric 
ComputePythonDirForWindows(llvm::SmallVectorImpl<char> & path)3954ba319b5SDimitry Andric void ScriptInterpreterPython::ComputePythonDirForWindows(
3964ba319b5SDimitry Andric     llvm::SmallVectorImpl<char> &path) {
3974ba319b5SDimitry Andric   auto style = llvm::sys::path::Style::windows;
3984ba319b5SDimitry Andric   llvm::sys::path::remove_filename(path, style);
3994ba319b5SDimitry Andric   llvm::sys::path::append(path, style, "lib", "site-packages");
4004ba319b5SDimitry Andric 
4014ba319b5SDimitry Andric   // This will be injected directly through FileSpec.GetDirectory().SetString(),
4024ba319b5SDimitry Andric   // so we need to normalize manually.
4034ba319b5SDimitry Andric   std::replace(path.begin(), path.end(), '\\', '/');
4044ba319b5SDimitry Andric }
4054ba319b5SDimitry Andric 
GetPythonDir()4064ba319b5SDimitry Andric FileSpec ScriptInterpreterPython::GetPythonDir() {
4074ba319b5SDimitry Andric   static FileSpec g_spec = []() {
4084ba319b5SDimitry Andric     FileSpec spec = HostInfo::GetShlibDir();
4094ba319b5SDimitry Andric     if (!spec)
4104ba319b5SDimitry Andric       return FileSpec();
4114ba319b5SDimitry Andric     llvm::SmallString<64> path;
4124ba319b5SDimitry Andric     spec.GetPath(path);
4134ba319b5SDimitry Andric 
4144ba319b5SDimitry Andric #if defined(__APPLE__)
4154ba319b5SDimitry Andric     ComputePythonDirForApple(path);
4164ba319b5SDimitry Andric #elif defined(_WIN32)
4174ba319b5SDimitry Andric     ComputePythonDirForWindows(path);
4184ba319b5SDimitry Andric #else
4194ba319b5SDimitry Andric     ComputePythonDirForPosix(path);
4204ba319b5SDimitry Andric #endif
4214ba319b5SDimitry Andric     spec.GetDirectory().SetString(path);
4224ba319b5SDimitry Andric     return spec;
4234ba319b5SDimitry Andric   }();
4244ba319b5SDimitry Andric   return g_spec;
4254ba319b5SDimitry Andric }
4264ba319b5SDimitry Andric 
GetPluginName()427435933ddSDimitry Andric lldb_private::ConstString ScriptInterpreterPython::GetPluginName() {
4289f2f44ceSEd Maste   return GetPluginNameStatic();
4299f2f44ceSEd Maste }
4309f2f44ceSEd Maste 
GetPluginVersion()431435933ddSDimitry Andric uint32_t ScriptInterpreterPython::GetPluginVersion() { return 1; }
4329f2f44ceSEd Maste 
IOHandlerActivated(IOHandler & io_handler)433435933ddSDimitry Andric void ScriptInterpreterPython::IOHandlerActivated(IOHandler &io_handler) {
4349f2f44ceSEd Maste   const char *instructions = nullptr;
4359f2f44ceSEd Maste 
436435933ddSDimitry Andric   switch (m_active_io_handler) {
4379f2f44ceSEd Maste   case eIOHandlerNone:
4389f2f44ceSEd Maste     break;
4399f2f44ceSEd Maste   case eIOHandlerBreakpoint:
4409f2f44ceSEd Maste     instructions = R"(Enter your Python command(s). Type 'DONE' to end.
4419f2f44ceSEd Maste def function (frame, bp_loc, internal_dict):
4429f2f44ceSEd Maste     """frame: the lldb.SBFrame for the location at which you stopped
4439f2f44ceSEd Maste        bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information
4449f2f44ceSEd Maste        internal_dict: an LLDB support object not to be used"""
4459f2f44ceSEd Maste )";
4469f2f44ceSEd Maste     break;
4479f2f44ceSEd Maste   case eIOHandlerWatchpoint:
4489f2f44ceSEd Maste     instructions = "Enter your Python command(s). Type 'DONE' to end.\n";
4499f2f44ceSEd Maste     break;
4509f2f44ceSEd Maste   }
4519f2f44ceSEd Maste 
452435933ddSDimitry Andric   if (instructions) {
4539f2f44ceSEd Maste     StreamFileSP output_sp(io_handler.GetOutputStreamFile());
454435933ddSDimitry Andric     if (output_sp) {
4559f2f44ceSEd Maste       output_sp->PutCString(instructions);
4569f2f44ceSEd Maste       output_sp->Flush();
4579f2f44ceSEd Maste     }
4589f2f44ceSEd Maste   }
4599f2f44ceSEd Maste }
4609f2f44ceSEd Maste 
IOHandlerInputComplete(IOHandler & io_handler,std::string & data)461435933ddSDimitry Andric void ScriptInterpreterPython::IOHandlerInputComplete(IOHandler &io_handler,
462435933ddSDimitry Andric                                                      std::string &data) {
4639f2f44ceSEd Maste   io_handler.SetIsDone(true);
4649f2f44ceSEd Maste   bool batch_mode = m_interpreter.GetBatchCommandMode();
4659f2f44ceSEd Maste 
466435933ddSDimitry Andric   switch (m_active_io_handler) {
4679f2f44ceSEd Maste   case eIOHandlerNone:
4689f2f44ceSEd Maste     break;
469435933ddSDimitry Andric   case eIOHandlerBreakpoint: {
470435933ddSDimitry Andric     std::vector<BreakpointOptions *> *bp_options_vec =
471435933ddSDimitry Andric         (std::vector<BreakpointOptions *> *)io_handler.GetUserData();
472435933ddSDimitry Andric     for (auto bp_options : *bp_options_vec) {
4739f2f44ceSEd Maste       if (!bp_options)
4749f2f44ceSEd Maste         continue;
4759f2f44ceSEd Maste 
476435933ddSDimitry Andric       auto data_ap = llvm::make_unique<CommandDataPython>();
477435933ddSDimitry Andric       if (!data_ap)
4789f2f44ceSEd Maste         break;
4799f2f44ceSEd Maste       data_ap->user_source.SplitIntoLines(data);
4809f2f44ceSEd Maste 
481435933ddSDimitry Andric       if (GenerateBreakpointCommandCallbackData(data_ap->user_source,
482435933ddSDimitry Andric                                                 data_ap->script_source)
483435933ddSDimitry Andric               .Success()) {
484435933ddSDimitry Andric         auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>(
485435933ddSDimitry Andric             std::move(data_ap));
486435933ddSDimitry Andric         bp_options->SetCallback(
487435933ddSDimitry Andric             ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
488435933ddSDimitry Andric       } else if (!batch_mode) {
4899f2f44ceSEd Maste         StreamFileSP error_sp = io_handler.GetErrorStreamFile();
490435933ddSDimitry Andric         if (error_sp) {
4919f2f44ceSEd Maste           error_sp->Printf("Warning: No command attached to breakpoint.\n");
4929f2f44ceSEd Maste           error_sp->Flush();
4939f2f44ceSEd Maste         }
4949f2f44ceSEd Maste       }
4959f2f44ceSEd Maste     }
4969f2f44ceSEd Maste     m_active_io_handler = eIOHandlerNone;
497435933ddSDimitry Andric   } break;
498435933ddSDimitry Andric   case eIOHandlerWatchpoint: {
499435933ddSDimitry Andric     WatchpointOptions *wp_options =
500435933ddSDimitry Andric         (WatchpointOptions *)io_handler.GetUserData();
501435933ddSDimitry Andric     auto data_ap = llvm::make_unique<WatchpointOptions::CommandData>();
502435933ddSDimitry Andric     data_ap->user_source.SplitIntoLines(data);
503435933ddSDimitry Andric 
504435933ddSDimitry Andric     if (GenerateWatchpointCommandCallbackData(data_ap->user_source,
505435933ddSDimitry Andric                                               data_ap->script_source)) {
506435933ddSDimitry Andric       auto baton_sp =
507435933ddSDimitry Andric           std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_ap));
508435933ddSDimitry Andric       wp_options->SetCallback(
509435933ddSDimitry Andric           ScriptInterpreterPython::WatchpointCallbackFunction, baton_sp);
510435933ddSDimitry Andric     } else if (!batch_mode) {
511435933ddSDimitry Andric       StreamFileSP error_sp = io_handler.GetErrorStreamFile();
512435933ddSDimitry Andric       if (error_sp) {
513435933ddSDimitry Andric         error_sp->Printf("Warning: No command attached to breakpoint.\n");
514435933ddSDimitry Andric         error_sp->Flush();
5159f2f44ceSEd Maste       }
516435933ddSDimitry Andric     }
517435933ddSDimitry Andric     m_active_io_handler = eIOHandlerNone;
518435933ddSDimitry Andric   } break;
5199f2f44ceSEd Maste   }
5209f2f44ceSEd Maste }
5219f2f44ceSEd Maste 
ResetOutputFileHandle(FILE * fh)522435933ddSDimitry Andric void ScriptInterpreterPython::ResetOutputFileHandle(FILE *fh) {}
5239f2f44ceSEd Maste 
SaveTerminalState(int fd)524435933ddSDimitry Andric void ScriptInterpreterPython::SaveTerminalState(int fd) {
5259f2f44ceSEd Maste   // Python mucks with the terminal state of STDIN. If we can possibly avoid
5269f2f44ceSEd Maste   // this by setting the file handles up correctly prior to entering the
5274ba319b5SDimitry Andric   // interpreter we should. For now we save and restore the terminal state on
5284ba319b5SDimitry Andric   // the input file handle.
5299f2f44ceSEd Maste   m_terminal_state.Save(fd, false);
5309f2f44ceSEd Maste }
5319f2f44ceSEd Maste 
RestoreTerminalState()532435933ddSDimitry Andric void ScriptInterpreterPython::RestoreTerminalState() {
5339f2f44ceSEd Maste   // Python mucks with the terminal state of STDIN. If we can possibly avoid
5349f2f44ceSEd Maste   // this by setting the file handles up correctly prior to entering the
5354ba319b5SDimitry Andric   // interpreter we should. For now we save and restore the terminal state on
5364ba319b5SDimitry Andric   // the input file handle.
5379f2f44ceSEd Maste   m_terminal_state.Restore();
5389f2f44ceSEd Maste }
5399f2f44ceSEd Maste 
LeaveSession()540435933ddSDimitry Andric void ScriptInterpreterPython::LeaveSession() {
5419f2f44ceSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
5429f2f44ceSEd Maste   if (log)
5439f2f44ceSEd Maste     log->PutCString("ScriptInterpreterPython::LeaveSession()");
5449f2f44ceSEd Maste 
5454ba319b5SDimitry Andric   // checking that we have a valid thread state - since we use our own
5464ba319b5SDimitry Andric   // threading and locking in some (rare) cases during cleanup Python may end
5474ba319b5SDimitry Andric   // up believing we have no thread state and PyImport_AddModule will crash if
5484ba319b5SDimitry Andric   // that is the case - since that seems to only happen when destroying the
5494ba319b5SDimitry Andric   // SBDebugger, we can make do without clearing up stdout and stderr
5509f2f44ceSEd Maste 
5519f2f44ceSEd Maste   // rdar://problem/11292882
552435933ddSDimitry Andric   // When the current thread state is NULL, PyThreadState_Get() issues a fatal
553435933ddSDimitry Andric   // error.
554435933ddSDimitry Andric   if (PyThreadState_GetDict()) {
5559f2f44ceSEd Maste     PythonDictionary &sys_module_dict = GetSysModuleDictionary();
556435933ddSDimitry Andric     if (sys_module_dict.IsValid()) {
557435933ddSDimitry Andric       if (m_saved_stdin.IsValid()) {
5589f2f44ceSEd Maste         sys_module_dict.SetItemForKey(PythonString("stdin"), m_saved_stdin);
5599f2f44ceSEd Maste         m_saved_stdin.Reset();
5609f2f44ceSEd Maste       }
561435933ddSDimitry Andric       if (m_saved_stdout.IsValid()) {
5629f2f44ceSEd Maste         sys_module_dict.SetItemForKey(PythonString("stdout"), m_saved_stdout);
5639f2f44ceSEd Maste         m_saved_stdout.Reset();
5649f2f44ceSEd Maste       }
565435933ddSDimitry Andric       if (m_saved_stderr.IsValid()) {
5669f2f44ceSEd Maste         sys_module_dict.SetItemForKey(PythonString("stderr"), m_saved_stderr);
5679f2f44ceSEd Maste         m_saved_stderr.Reset();
5689f2f44ceSEd Maste       }
5699f2f44ceSEd Maste     }
5709f2f44ceSEd Maste   }
5719f2f44ceSEd Maste 
5729f2f44ceSEd Maste   m_session_is_active = false;
5739f2f44ceSEd Maste }
5749f2f44ceSEd Maste 
SetStdHandle(File & file,const char * py_name,PythonFile & save_file,const char * mode)575435933ddSDimitry Andric bool ScriptInterpreterPython::SetStdHandle(File &file, const char *py_name,
576435933ddSDimitry Andric                                            PythonFile &save_file,
577435933ddSDimitry Andric                                            const char *mode) {
578435933ddSDimitry Andric   if (file.IsValid()) {
5794bb0738eSEd Maste     // Flush the file before giving it to python to avoid interleaved output.
5804bb0738eSEd Maste     file.Flush();
5814bb0738eSEd Maste 
5824bb0738eSEd Maste     PythonDictionary &sys_module_dict = GetSysModuleDictionary();
5834bb0738eSEd Maste 
584435933ddSDimitry Andric     save_file = sys_module_dict.GetItemForKey(PythonString(py_name))
585435933ddSDimitry Andric                     .AsType<PythonFile>();
5864bb0738eSEd Maste 
5874bb0738eSEd Maste     PythonFile new_file(file, mode);
5884bb0738eSEd Maste     sys_module_dict.SetItemForKey(PythonString(py_name), new_file);
5894bb0738eSEd Maste     return true;
590435933ddSDimitry Andric   } else
5914bb0738eSEd Maste     save_file.Reset();
5924bb0738eSEd Maste   return false;
5934bb0738eSEd Maste }
5944bb0738eSEd Maste 
EnterSession(uint16_t on_entry_flags,FILE * in,FILE * out,FILE * err)595435933ddSDimitry Andric bool ScriptInterpreterPython::EnterSession(uint16_t on_entry_flags, FILE *in,
596435933ddSDimitry Andric                                            FILE *out, FILE *err) {
597435933ddSDimitry Andric   // If we have already entered the session, without having officially 'left'
5984ba319b5SDimitry Andric   // it, then there is no need to 'enter' it again.
5999f2f44ceSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
600435933ddSDimitry Andric   if (m_session_is_active) {
6019f2f44ceSEd Maste     if (log)
602435933ddSDimitry Andric       log->Printf(
603435933ddSDimitry Andric           "ScriptInterpreterPython::EnterSession(on_entry_flags=0x%" PRIx16
604435933ddSDimitry Andric           ") session is already active, returning without doing anything",
605435933ddSDimitry Andric           on_entry_flags);
6069f2f44ceSEd Maste     return false;
6079f2f44ceSEd Maste   }
6089f2f44ceSEd Maste 
6099f2f44ceSEd Maste   if (log)
610435933ddSDimitry Andric     log->Printf(
611435933ddSDimitry Andric         "ScriptInterpreterPython::EnterSession(on_entry_flags=0x%" PRIx16 ")",
612435933ddSDimitry Andric         on_entry_flags);
6139f2f44ceSEd Maste 
6149f2f44ceSEd Maste   m_session_is_active = true;
6159f2f44ceSEd Maste 
6169f2f44ceSEd Maste   StreamString run_string;
6179f2f44ceSEd Maste 
618435933ddSDimitry Andric   if (on_entry_flags & Locker::InitGlobals) {
619435933ddSDimitry Andric     run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
620435933ddSDimitry Andric                       m_dictionary_name.c_str(),
621435933ddSDimitry Andric                       GetCommandInterpreter().GetDebugger().GetID());
622435933ddSDimitry Andric     run_string.Printf(
623435933ddSDimitry Andric         "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")",
624435933ddSDimitry Andric         GetCommandInterpreter().GetDebugger().GetID());
6259f2f44ceSEd Maste     run_string.PutCString("; lldb.target = lldb.debugger.GetSelectedTarget()");
6269f2f44ceSEd Maste     run_string.PutCString("; lldb.process = lldb.target.GetProcess()");
6279f2f44ceSEd Maste     run_string.PutCString("; lldb.thread = lldb.process.GetSelectedThread ()");
6289f2f44ceSEd Maste     run_string.PutCString("; lldb.frame = lldb.thread.GetSelectedFrame ()");
6299f2f44ceSEd Maste     run_string.PutCString("')");
630435933ddSDimitry Andric   } else {
6314ba319b5SDimitry Andric     // If we aren't initing the globals, we should still always set the
6324ba319b5SDimitry Andric     // debugger (since that is always unique.)
633435933ddSDimitry Andric     run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
634435933ddSDimitry Andric                       m_dictionary_name.c_str(),
635435933ddSDimitry Andric                       GetCommandInterpreter().GetDebugger().GetID());
636435933ddSDimitry Andric     run_string.Printf(
637435933ddSDimitry Andric         "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")",
638435933ddSDimitry Andric         GetCommandInterpreter().GetDebugger().GetID());
6399f2f44ceSEd Maste     run_string.PutCString("')");
6409f2f44ceSEd Maste   }
6419f2f44ceSEd Maste 
6429f2f44ceSEd Maste   PyRun_SimpleString(run_string.GetData());
6439f2f44ceSEd Maste   run_string.Clear();
6449f2f44ceSEd Maste 
6459f2f44ceSEd Maste   PythonDictionary &sys_module_dict = GetSysModuleDictionary();
646435933ddSDimitry Andric   if (sys_module_dict.IsValid()) {
6479f2f44ceSEd Maste     File in_file(in, false);
6489f2f44ceSEd Maste     File out_file(out, false);
6499f2f44ceSEd Maste     File err_file(err, false);
6509f2f44ceSEd Maste 
6519f2f44ceSEd Maste     lldb::StreamFileSP in_sp;
6529f2f44ceSEd Maste     lldb::StreamFileSP out_sp;
6539f2f44ceSEd Maste     lldb::StreamFileSP err_sp;
6549f2f44ceSEd Maste     if (!in_file.IsValid() || !out_file.IsValid() || !err_file.IsValid())
655435933ddSDimitry Andric       m_interpreter.GetDebugger().AdoptTopIOHandlerFilesIfInvalid(in_sp, out_sp,
656435933ddSDimitry Andric                                                                   err_sp);
6579f2f44ceSEd Maste 
658435933ddSDimitry Andric     if (on_entry_flags & Locker::NoSTDIN) {
6599f2f44ceSEd Maste       m_saved_stdin.Reset();
660435933ddSDimitry Andric     } else {
661435933ddSDimitry Andric       if (!SetStdHandle(in_file, "stdin", m_saved_stdin, "r")) {
6624bb0738eSEd Maste         if (in_sp)
6634bb0738eSEd Maste           SetStdHandle(in_sp->GetFile(), "stdin", m_saved_stdin, "r");
6649f2f44ceSEd Maste       }
6654bb0738eSEd Maste     }
6664bb0738eSEd Maste 
667435933ddSDimitry Andric     if (!SetStdHandle(out_file, "stdout", m_saved_stdout, "w")) {
6684bb0738eSEd Maste       if (out_sp)
6694bb0738eSEd Maste         SetStdHandle(out_sp->GetFile(), "stdout", m_saved_stdout, "w");
6704bb0738eSEd Maste     }
6714bb0738eSEd Maste 
672435933ddSDimitry Andric     if (!SetStdHandle(err_file, "stderr", m_saved_stderr, "w")) {
6734bb0738eSEd Maste       if (err_sp)
6744bb0738eSEd Maste         SetStdHandle(err_sp->GetFile(), "stderr", m_saved_stderr, "w");
6754bb0738eSEd Maste     }
6769f2f44ceSEd Maste   }
6779f2f44ceSEd Maste 
6789f2f44ceSEd Maste   if (PyErr_Occurred())
6799f2f44ceSEd Maste     PyErr_Clear();
6809f2f44ceSEd Maste 
6819f2f44ceSEd Maste   return true;
6829f2f44ceSEd Maste }
6839f2f44ceSEd Maste 
GetMainModule()684435933ddSDimitry Andric PythonObject &ScriptInterpreterPython::GetMainModule() {
6859f2f44ceSEd Maste   if (!m_main_module.IsValid())
6869f2f44ceSEd Maste     m_main_module.Reset(PyRefType::Borrowed, PyImport_AddModule("__main__"));
6879f2f44ceSEd Maste   return m_main_module;
6889f2f44ceSEd Maste }
6899f2f44ceSEd Maste 
GetSessionDictionary()690435933ddSDimitry Andric PythonDictionary &ScriptInterpreterPython::GetSessionDictionary() {
6919f2f44ceSEd Maste   if (m_session_dict.IsValid())
6929f2f44ceSEd Maste     return m_session_dict;
6939f2f44ceSEd Maste 
6949f2f44ceSEd Maste   PythonObject &main_module = GetMainModule();
6959f2f44ceSEd Maste   if (!main_module.IsValid())
6969f2f44ceSEd Maste     return m_session_dict;
6979f2f44ceSEd Maste 
698435933ddSDimitry Andric   PythonDictionary main_dict(PyRefType::Borrowed,
699435933ddSDimitry Andric                              PyModule_GetDict(main_module.get()));
7009f2f44ceSEd Maste   if (!main_dict.IsValid())
7019f2f44ceSEd Maste     return m_session_dict;
7029f2f44ceSEd Maste 
7039f2f44ceSEd Maste   PythonObject item = main_dict.GetItemForKey(PythonString(m_dictionary_name));
7049f2f44ceSEd Maste   m_session_dict.Reset(PyRefType::Borrowed, item.get());
7059f2f44ceSEd Maste   return m_session_dict;
7069f2f44ceSEd Maste }
7079f2f44ceSEd Maste 
GetSysModuleDictionary()708435933ddSDimitry Andric PythonDictionary &ScriptInterpreterPython::GetSysModuleDictionary() {
7099f2f44ceSEd Maste   if (m_sys_module_dict.IsValid())
7109f2f44ceSEd Maste     return m_sys_module_dict;
7119f2f44ceSEd Maste 
7129f2f44ceSEd Maste   PythonObject sys_module(PyRefType::Borrowed, PyImport_AddModule("sys"));
7139f2f44ceSEd Maste   if (sys_module.IsValid())
714435933ddSDimitry Andric     m_sys_module_dict.Reset(PyRefType::Borrowed,
715435933ddSDimitry Andric                             PyModule_GetDict(sys_module.get()));
7169f2f44ceSEd Maste   return m_sys_module_dict;
7179f2f44ceSEd Maste }
7189f2f44ceSEd Maste 
GenerateUniqueName(const char * base_name_wanted,uint32_t & functions_counter,const void * name_token=nullptr)719435933ddSDimitry Andric static std::string GenerateUniqueName(const char *base_name_wanted,
7209f2f44ceSEd Maste                                       uint32_t &functions_counter,
721435933ddSDimitry Andric                                       const void *name_token = nullptr) {
7229f2f44ceSEd Maste   StreamString sstr;
7239f2f44ceSEd Maste 
7249f2f44ceSEd Maste   if (!base_name_wanted)
7259f2f44ceSEd Maste     return std::string();
7269f2f44ceSEd Maste 
7279f2f44ceSEd Maste   if (!name_token)
7289f2f44ceSEd Maste     sstr.Printf("%s_%d", base_name_wanted, functions_counter++);
7299f2f44ceSEd Maste   else
7309f2f44ceSEd Maste     sstr.Printf("%s_%p", base_name_wanted, name_token);
7319f2f44ceSEd Maste 
7329f2f44ceSEd Maste   return sstr.GetString();
7339f2f44ceSEd Maste }
7349f2f44ceSEd Maste 
GetEmbeddedInterpreterModuleObjects()735435933ddSDimitry Andric bool ScriptInterpreterPython::GetEmbeddedInterpreterModuleObjects() {
7369f2f44ceSEd Maste   if (m_run_one_line_function.IsValid())
7379f2f44ceSEd Maste     return true;
7389f2f44ceSEd Maste 
739435933ddSDimitry Andric   PythonObject module(PyRefType::Borrowed,
740435933ddSDimitry Andric                       PyImport_AddModule("lldb.embedded_interpreter"));
7419f2f44ceSEd Maste   if (!module.IsValid())
7429f2f44ceSEd Maste     return false;
7439f2f44ceSEd Maste 
744435933ddSDimitry Andric   PythonDictionary module_dict(PyRefType::Borrowed,
745435933ddSDimitry Andric                                PyModule_GetDict(module.get()));
7469f2f44ceSEd Maste   if (!module_dict.IsValid())
7479f2f44ceSEd Maste     return false;
7489f2f44ceSEd Maste 
749435933ddSDimitry Andric   m_run_one_line_function =
750435933ddSDimitry Andric       module_dict.GetItemForKey(PythonString("run_one_line"));
751435933ddSDimitry Andric   m_run_one_line_str_global =
752435933ddSDimitry Andric       module_dict.GetItemForKey(PythonString("g_run_one_line_str"));
7539f2f44ceSEd Maste   return m_run_one_line_function.IsValid();
7549f2f44ceSEd Maste }
7559f2f44ceSEd Maste 
ReadThreadBytesReceived(void * baton,const void * src,size_t src_len)756435933ddSDimitry Andric static void ReadThreadBytesReceived(void *baton, const void *src,
757435933ddSDimitry Andric                                     size_t src_len) {
758435933ddSDimitry Andric   if (src && src_len) {
7599f2f44ceSEd Maste     Stream *strm = (Stream *)baton;
7609f2f44ceSEd Maste     strm->Write(src, src_len);
7619f2f44ceSEd Maste     strm->Flush();
7629f2f44ceSEd Maste   }
7639f2f44ceSEd Maste }
7649f2f44ceSEd Maste 
ExecuteOneLine(llvm::StringRef command,CommandReturnObject * result,const ExecuteScriptOptions & options)765435933ddSDimitry Andric bool ScriptInterpreterPython::ExecuteOneLine(
7664ba319b5SDimitry Andric     llvm::StringRef command, CommandReturnObject *result,
767435933ddSDimitry Andric     const ExecuteScriptOptions &options) {
7684ba319b5SDimitry Andric   std::string command_str = command.str();
7694ba319b5SDimitry Andric 
7709f2f44ceSEd Maste   if (!m_valid_session)
7719f2f44ceSEd Maste     return false;
7729f2f44ceSEd Maste 
7734ba319b5SDimitry Andric   if (!command.empty()) {
774435933ddSDimitry Andric     // We want to call run_one_line, passing in the dictionary and the command
7754ba319b5SDimitry Andric     // string.  We cannot do this through PyRun_SimpleString here because the
7764ba319b5SDimitry Andric     // command string may contain escaped characters, and putting it inside
777435933ddSDimitry Andric     // another string to pass to PyRun_SimpleString messes up the escaping.  So
7784ba319b5SDimitry Andric     // we use the following more complicated method to pass the command string
7794ba319b5SDimitry Andric     // directly down to Python.
7809f2f44ceSEd Maste     Debugger &debugger = m_interpreter.GetDebugger();
7819f2f44ceSEd Maste 
7829f2f44ceSEd Maste     StreamFileSP input_file_sp;
7839f2f44ceSEd Maste     StreamFileSP output_file_sp;
7849f2f44ceSEd Maste     StreamFileSP error_file_sp;
785435933ddSDimitry Andric     Communication output_comm(
786435933ddSDimitry Andric         "lldb.ScriptInterpreterPython.ExecuteOneLine.comm");
7879f2f44ceSEd Maste     bool join_read_thread = false;
788435933ddSDimitry Andric     if (options.GetEnableIO()) {
789435933ddSDimitry Andric       if (result) {
7909f2f44ceSEd Maste         input_file_sp = debugger.GetInputFile();
791435933ddSDimitry Andric         // Set output to a temporary file so we can forward the results on to
792435933ddSDimitry Andric         // the result object
7939f2f44ceSEd Maste 
7949f2f44ceSEd Maste         Pipe pipe;
7955517e702SDimitry Andric         Status pipe_result = pipe.CreateNew(false);
796435933ddSDimitry Andric         if (pipe_result.Success()) {
7979f2f44ceSEd Maste #if defined(_WIN32)
7989f2f44ceSEd Maste           lldb::file_t read_file = pipe.GetReadNativeHandle();
7999f2f44ceSEd Maste           pipe.ReleaseReadFileDescriptor();
800435933ddSDimitry Andric           std::unique_ptr<ConnectionGenericFile> conn_ap(
801435933ddSDimitry Andric               new ConnectionGenericFile(read_file, true));
8029f2f44ceSEd Maste #else
803435933ddSDimitry Andric           std::unique_ptr<ConnectionFileDescriptor> conn_ap(
804435933ddSDimitry Andric               new ConnectionFileDescriptor(pipe.ReleaseReadFileDescriptor(),
805435933ddSDimitry Andric                                            true));
8069f2f44ceSEd Maste #endif
807435933ddSDimitry Andric           if (conn_ap->IsConnected()) {
8089f2f44ceSEd Maste             output_comm.SetConnection(conn_ap.release());
809435933ddSDimitry Andric             output_comm.SetReadThreadBytesReceivedCallback(
810435933ddSDimitry Andric                 ReadThreadBytesReceived, &result->GetOutputStream());
8119f2f44ceSEd Maste             output_comm.StartReadThread();
8129f2f44ceSEd Maste             join_read_thread = true;
813435933ddSDimitry Andric             FILE *outfile_handle =
814435933ddSDimitry Andric                 fdopen(pipe.ReleaseWriteFileDescriptor(), "w");
8159f2f44ceSEd Maste             output_file_sp.reset(new StreamFile(outfile_handle, true));
8169f2f44ceSEd Maste             error_file_sp = output_file_sp;
8179f2f44ceSEd Maste             if (outfile_handle)
8189f2f44ceSEd Maste               ::setbuf(outfile_handle, nullptr);
8199f2f44ceSEd Maste 
820435933ddSDimitry Andric             result->SetImmediateOutputFile(
821435933ddSDimitry Andric                 debugger.GetOutputFile()->GetFile().GetStream());
822435933ddSDimitry Andric             result->SetImmediateErrorFile(
823435933ddSDimitry Andric                 debugger.GetErrorFile()->GetFile().GetStream());
8249f2f44ceSEd Maste           }
8259f2f44ceSEd Maste         }
8269f2f44ceSEd Maste       }
8279f2f44ceSEd Maste       if (!input_file_sp || !output_file_sp || !error_file_sp)
828435933ddSDimitry Andric         debugger.AdoptTopIOHandlerFilesIfInvalid(input_file_sp, output_file_sp,
829435933ddSDimitry Andric                                                  error_file_sp);
830435933ddSDimitry Andric     } else {
8319f2f44ceSEd Maste       input_file_sp.reset(new StreamFile());
832*b5893f02SDimitry Andric       FileSystem::Instance().Open(input_file_sp->GetFile(),
833*b5893f02SDimitry Andric                                   FileSpec(FileSystem::DEV_NULL),
834435933ddSDimitry Andric                                   File::eOpenOptionRead);
835*b5893f02SDimitry Andric 
8369f2f44ceSEd Maste       output_file_sp.reset(new StreamFile());
837*b5893f02SDimitry Andric       FileSystem::Instance().Open(output_file_sp->GetFile(),
838*b5893f02SDimitry Andric                                   FileSpec(FileSystem::DEV_NULL),
839435933ddSDimitry Andric                                   File::eOpenOptionWrite);
840*b5893f02SDimitry Andric 
8419f2f44ceSEd Maste       error_file_sp = output_file_sp;
8429f2f44ceSEd Maste     }
8439f2f44ceSEd Maste 
8449f2f44ceSEd Maste     FILE *in_file = input_file_sp->GetFile().GetStream();
8459f2f44ceSEd Maste     FILE *out_file = output_file_sp->GetFile().GetStream();
8469f2f44ceSEd Maste     FILE *err_file = error_file_sp->GetFile().GetStream();
8479f2f44ceSEd Maste     bool success = false;
8489f2f44ceSEd Maste     {
8494ba319b5SDimitry Andric       // WARNING!  It's imperative that this RAII scope be as tight as
8504ba319b5SDimitry Andric       // possible. In particular, the scope must end *before* we try to join
8514ba319b5SDimitry Andric       // the read thread.  The reason for this is that a pre-requisite for
8524ba319b5SDimitry Andric       // joining the read thread is that we close the write handle (to break
8534ba319b5SDimitry Andric       // the pipe and cause it to wake up and exit).  But acquiring the GIL as
8544ba319b5SDimitry Andric       // below will redirect Python's stdio to use this same handle.  If we
8554ba319b5SDimitry Andric       // close the handle while Python is still using it, bad things will
8564ba319b5SDimitry Andric       // happen.
857435933ddSDimitry Andric       Locker locker(
858435933ddSDimitry Andric           this,
8599f2f44ceSEd Maste           ScriptInterpreterPython::Locker::AcquireLock |
8609f2f44ceSEd Maste               ScriptInterpreterPython::Locker::InitSession |
861435933ddSDimitry Andric               (options.GetSetLLDBGlobals()
862435933ddSDimitry Andric                    ? ScriptInterpreterPython::Locker::InitGlobals
863435933ddSDimitry Andric                    : 0) |
8649f2f44ceSEd Maste               ((result && result->GetInteractive()) ? 0 : Locker::NoSTDIN),
8659f2f44ceSEd Maste           ScriptInterpreterPython::Locker::FreeAcquiredLock |
8669f2f44ceSEd Maste               ScriptInterpreterPython::Locker::TearDownSession,
867435933ddSDimitry Andric           in_file, out_file, err_file);
8689f2f44ceSEd Maste 
8699f2f44ceSEd Maste       // Find the correct script interpreter dictionary in the main module.
8709f2f44ceSEd Maste       PythonDictionary &session_dict = GetSessionDictionary();
871435933ddSDimitry Andric       if (session_dict.IsValid()) {
872435933ddSDimitry Andric         if (GetEmbeddedInterpreterModuleObjects()) {
873435933ddSDimitry Andric           if (PyCallable_Check(m_run_one_line_function.get())) {
874435933ddSDimitry Andric             PythonObject pargs(
875435933ddSDimitry Andric                 PyRefType::Owned,
8764ba319b5SDimitry Andric                 Py_BuildValue("(Os)", session_dict.get(), command_str.c_str()));
877435933ddSDimitry Andric             if (pargs.IsValid()) {
878435933ddSDimitry Andric               PythonObject return_value(
879435933ddSDimitry Andric                   PyRefType::Owned,
880435933ddSDimitry Andric                   PyObject_CallObject(m_run_one_line_function.get(),
881435933ddSDimitry Andric                                       pargs.get()));
8829f2f44ceSEd Maste               if (return_value.IsValid())
8839f2f44ceSEd Maste                 success = true;
884435933ddSDimitry Andric               else if (options.GetMaskoutErrors() && PyErr_Occurred()) {
8859f2f44ceSEd Maste                 PyErr_Print();
8869f2f44ceSEd Maste                 PyErr_Clear();
8879f2f44ceSEd Maste               }
8889f2f44ceSEd Maste             }
8899f2f44ceSEd Maste           }
8909f2f44ceSEd Maste         }
8919f2f44ceSEd Maste       }
8929f2f44ceSEd Maste 
8939f2f44ceSEd Maste       // Flush our output and error file handles
8949f2f44ceSEd Maste       ::fflush(out_file);
8959f2f44ceSEd Maste       if (out_file != err_file)
8969f2f44ceSEd Maste         ::fflush(err_file);
8979f2f44ceSEd Maste     }
8989f2f44ceSEd Maste 
899435933ddSDimitry Andric     if (join_read_thread) {
9004ba319b5SDimitry Andric       // Close the write end of the pipe since we are done with our one line
9014ba319b5SDimitry Andric       // script. This should cause the read thread that output_comm is using to
9024ba319b5SDimitry Andric       // exit
9039f2f44ceSEd Maste       output_file_sp->GetFile().Close();
9044ba319b5SDimitry Andric       // The close above should cause this thread to exit when it gets to the
9054ba319b5SDimitry Andric       // end of file, so let it get all its data
9069f2f44ceSEd Maste       output_comm.JoinReadThread();
9079f2f44ceSEd Maste       // Now we can close the read end of the pipe
9089f2f44ceSEd Maste       output_comm.Disconnect();
9099f2f44ceSEd Maste     }
9109f2f44ceSEd Maste 
9119f2f44ceSEd Maste     if (success)
9129f2f44ceSEd Maste       return true;
9139f2f44ceSEd Maste 
9149f2f44ceSEd Maste     // The one-liner failed.  Append the error message.
9154ba319b5SDimitry Andric     if (result) {
916435933ddSDimitry Andric       result->AppendErrorWithFormat(
9174ba319b5SDimitry Andric           "python failed attempting to evaluate '%s'\n", command_str.c_str());
9184ba319b5SDimitry Andric     }
9199f2f44ceSEd Maste     return false;
9209f2f44ceSEd Maste   }
9219f2f44ceSEd Maste 
9229f2f44ceSEd Maste   if (result)
9239f2f44ceSEd Maste     result->AppendError("empty command passed to python\n");
9249f2f44ceSEd Maste   return false;
9259f2f44ceSEd Maste }
9269f2f44ceSEd Maste 
927435933ddSDimitry Andric class IOHandlerPythonInterpreter : public IOHandler {
9289f2f44ceSEd Maste public:
IOHandlerPythonInterpreter(Debugger & debugger,ScriptInterpreterPython * python)9299f2f44ceSEd Maste   IOHandlerPythonInterpreter(Debugger &debugger,
930435933ddSDimitry Andric                              ScriptInterpreterPython *python)
931435933ddSDimitry Andric       : IOHandler(debugger, IOHandler::Type::PythonInterpreter),
932435933ddSDimitry Andric         m_python(python) {}
9339f2f44ceSEd Maste 
~IOHandlerPythonInterpreter()934435933ddSDimitry Andric   ~IOHandlerPythonInterpreter() override {}
9359f2f44ceSEd Maste 
GetControlSequence(char ch)936435933ddSDimitry Andric   ConstString GetControlSequence(char ch) override {
9379f2f44ceSEd Maste     if (ch == 'd')
9389f2f44ceSEd Maste       return ConstString("quit()\n");
9399f2f44ceSEd Maste     return ConstString();
9409f2f44ceSEd Maste   }
9419f2f44ceSEd Maste 
Run()942435933ddSDimitry Andric   void Run() override {
943435933ddSDimitry Andric     if (m_python) {
9449f2f44ceSEd Maste       int stdin_fd = GetInputFD();
945435933ddSDimitry Andric       if (stdin_fd >= 0) {
9469f2f44ceSEd Maste         Terminal terminal(stdin_fd);
9479f2f44ceSEd Maste         TerminalState terminal_state;
9489f2f44ceSEd Maste         const bool is_a_tty = terminal.IsATerminal();
9499f2f44ceSEd Maste 
950435933ddSDimitry Andric         if (is_a_tty) {
9519f2f44ceSEd Maste           terminal_state.Save(stdin_fd, false);
9529f2f44ceSEd Maste           terminal.SetCanonical(false);
9539f2f44ceSEd Maste           terminal.SetEcho(true);
9549f2f44ceSEd Maste         }
9559f2f44ceSEd Maste 
956435933ddSDimitry Andric         ScriptInterpreterPython::Locker locker(
957435933ddSDimitry Andric             m_python, ScriptInterpreterPython::Locker::AcquireLock |
9589f2f44ceSEd Maste                           ScriptInterpreterPython::Locker::InitSession |
9599f2f44ceSEd Maste                           ScriptInterpreterPython::Locker::InitGlobals,
9609f2f44ceSEd Maste             ScriptInterpreterPython::Locker::FreeAcquiredLock |
9619f2f44ceSEd Maste                 ScriptInterpreterPython::Locker::TearDownSession);
9629f2f44ceSEd Maste 
9634ba319b5SDimitry Andric         // The following call drops into the embedded interpreter loop and
9644ba319b5SDimitry Andric         // stays there until the user chooses to exit from the Python
9654ba319b5SDimitry Andric         // interpreter. This embedded interpreter will, as any Python code that
9664ba319b5SDimitry Andric         // performs I/O, unlock the GIL before a system call that can hang, and
9674ba319b5SDimitry Andric         // lock it when the syscall has returned.
9689f2f44ceSEd Maste 
969435933ddSDimitry Andric         // We need to surround the call to the embedded interpreter with calls
9704ba319b5SDimitry Andric         // to PyGILState_Ensure and PyGILState_Release (using the Locker
9714ba319b5SDimitry Andric         // above). This is because Python has a global lock which must be held
9724ba319b5SDimitry Andric         // whenever we want to touch any Python objects. Otherwise, if the user
9734ba319b5SDimitry Andric         // calls Python code, the interpreter state will be off, and things
9744ba319b5SDimitry Andric         // could hang (it's happened before).
9759f2f44ceSEd Maste 
9769f2f44ceSEd Maste         StreamString run_string;
977435933ddSDimitry Andric         run_string.Printf("run_python_interpreter (%s)",
978435933ddSDimitry Andric                           m_python->GetDictionaryName());
9799f2f44ceSEd Maste         PyRun_SimpleString(run_string.GetData());
9809f2f44ceSEd Maste 
9819f2f44ceSEd Maste         if (is_a_tty)
9829f2f44ceSEd Maste           terminal_state.Restore();
9839f2f44ceSEd Maste       }
9849f2f44ceSEd Maste     }
9859f2f44ceSEd Maste     SetIsDone(true);
9869f2f44ceSEd Maste   }
9879f2f44ceSEd Maste 
Cancel()988435933ddSDimitry Andric   void Cancel() override {}
9899f2f44ceSEd Maste 
Interrupt()990435933ddSDimitry Andric   bool Interrupt() override { return m_python->Interrupt(); }
9919f2f44ceSEd Maste 
GotEOF()992435933ddSDimitry Andric   void GotEOF() override {}
9939f2f44ceSEd Maste 
9949f2f44ceSEd Maste protected:
9959f2f44ceSEd Maste   ScriptInterpreterPython *m_python;
9969f2f44ceSEd Maste };
9979f2f44ceSEd Maste 
ExecuteInterpreterLoop()998435933ddSDimitry Andric void ScriptInterpreterPython::ExecuteInterpreterLoop() {
9995517e702SDimitry Andric   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
10005517e702SDimitry Andric   Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
10019f2f44ceSEd Maste 
10029f2f44ceSEd Maste   Debugger &debugger = GetCommandInterpreter().GetDebugger();
10039f2f44ceSEd Maste 
1004435933ddSDimitry Andric   // At the moment, the only time the debugger does not have an input file
10054ba319b5SDimitry Andric   // handle is when this is called directly from Python, in which case it is
10064ba319b5SDimitry Andric   // both dangerous and unnecessary (not to mention confusing) to try to embed
10074ba319b5SDimitry Andric   // a running interpreter loop inside the already running Python interpreter
10084ba319b5SDimitry Andric   // loop, so we won't do it.
10099f2f44ceSEd Maste 
10109f2f44ceSEd Maste   if (!debugger.GetInputFile()->GetFile().IsValid())
10119f2f44ceSEd Maste     return;
10129f2f44ceSEd Maste 
10139f2f44ceSEd Maste   IOHandlerSP io_handler_sp(new IOHandlerPythonInterpreter(debugger, this));
1014435933ddSDimitry Andric   if (io_handler_sp) {
10159f2f44ceSEd Maste     debugger.PushIOHandler(io_handler_sp);
10169f2f44ceSEd Maste   }
10179f2f44ceSEd Maste }
10189f2f44ceSEd Maste 
Interrupt()1019435933ddSDimitry Andric bool ScriptInterpreterPython::Interrupt() {
10209f2f44ceSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
10219f2f44ceSEd Maste 
1022435933ddSDimitry Andric   if (IsExecutingPython()) {
10234bb0738eSEd Maste     PyThreadState *state = PyThreadState_GET();
10249f2f44ceSEd Maste     if (!state)
10259f2f44ceSEd Maste       state = GetThreadState();
1026435933ddSDimitry Andric     if (state) {
10279f2f44ceSEd Maste       long tid = state->thread_id;
10289f2f44ceSEd Maste       PyThreadState_Swap(state);
10299f2f44ceSEd Maste       int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
10309f2f44ceSEd Maste       if (log)
1031435933ddSDimitry Andric         log->Printf("ScriptInterpreterPython::Interrupt() sending "
1032435933ddSDimitry Andric                     "PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...",
1033435933ddSDimitry Andric                     tid, num_threads);
10349f2f44ceSEd Maste       return true;
10359f2f44ceSEd Maste     }
10369f2f44ceSEd Maste   }
10379f2f44ceSEd Maste   if (log)
1038435933ddSDimitry Andric     log->Printf("ScriptInterpreterPython::Interrupt() python code not running, "
1039435933ddSDimitry Andric                 "can't interrupt");
10409f2f44ceSEd Maste   return false;
10419f2f44ceSEd Maste }
ExecuteOneLineWithReturn(llvm::StringRef in_string,ScriptInterpreter::ScriptReturnType return_type,void * ret_value,const ExecuteScriptOptions & options)1042435933ddSDimitry Andric bool ScriptInterpreterPython::ExecuteOneLineWithReturn(
10434ba319b5SDimitry Andric     llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type,
1044435933ddSDimitry Andric     void *ret_value, const ExecuteScriptOptions &options) {
10459f2f44ceSEd Maste 
1046435933ddSDimitry Andric   Locker locker(this, ScriptInterpreterPython::Locker::AcquireLock |
1047435933ddSDimitry Andric                           ScriptInterpreterPython::Locker::InitSession |
1048435933ddSDimitry Andric                           (options.GetSetLLDBGlobals()
1049435933ddSDimitry Andric                                ? ScriptInterpreterPython::Locker::InitGlobals
1050435933ddSDimitry Andric                                : 0) |
1051435933ddSDimitry Andric                           Locker::NoSTDIN,
1052435933ddSDimitry Andric                 ScriptInterpreterPython::Locker::FreeAcquiredLock |
1053435933ddSDimitry Andric                     ScriptInterpreterPython::Locker::TearDownSession);
10549f2f44ceSEd Maste 
10559f2f44ceSEd Maste   PythonObject py_return;
10569f2f44ceSEd Maste   PythonObject &main_module = GetMainModule();
1057435933ddSDimitry Andric   PythonDictionary globals(PyRefType::Borrowed,
1058435933ddSDimitry Andric                            PyModule_GetDict(main_module.get()));
10599f2f44ceSEd Maste   PythonObject py_error;
10609f2f44ceSEd Maste   bool ret_success = false;
10619f2f44ceSEd Maste   int success;
10629f2f44ceSEd Maste 
10639f2f44ceSEd Maste   PythonDictionary locals = GetSessionDictionary();
10649f2f44ceSEd Maste 
1065435933ddSDimitry Andric   if (!locals.IsValid()) {
1066435933ddSDimitry Andric     locals.Reset(
1067435933ddSDimitry Andric         PyRefType::Owned,
1068435933ddSDimitry Andric         PyObject_GetAttrString(globals.get(), m_dictionary_name.c_str()));
10699f2f44ceSEd Maste   }
10709f2f44ceSEd Maste 
10719f2f44ceSEd Maste   if (!locals.IsValid())
10729f2f44ceSEd Maste     locals = globals;
10739f2f44ceSEd Maste 
10749f2f44ceSEd Maste   py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
10759f2f44ceSEd Maste   if (py_error.IsValid())
10769f2f44ceSEd Maste     PyErr_Clear();
10779f2f44ceSEd Maste 
10784ba319b5SDimitry Andric   std::string as_string = in_string.str();
10799f2f44ceSEd Maste   { // scope for PythonInputReaderManager
10809f2f44ceSEd Maste     // PythonInputReaderManager py_input(options.GetEnableIO() ? this : NULL);
10814ba319b5SDimitry Andric     py_return.Reset(PyRefType::Owned,
10824ba319b5SDimitry Andric                     PyRun_String(as_string.c_str(), Py_eval_input,
10834ba319b5SDimitry Andric                                  globals.get(), locals.get()));
1084435933ddSDimitry Andric     if (!py_return.IsValid()) {
10859f2f44ceSEd Maste       py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
10869f2f44ceSEd Maste       if (py_error.IsValid())
10879f2f44ceSEd Maste         PyErr_Clear();
10889f2f44ceSEd Maste 
1089435933ddSDimitry Andric       py_return.Reset(PyRefType::Owned,
10904ba319b5SDimitry Andric                       PyRun_String(as_string.c_str(), Py_single_input,
10914ba319b5SDimitry Andric                                    globals.get(), locals.get()));
10929f2f44ceSEd Maste     }
10939f2f44ceSEd Maste   }
10949f2f44ceSEd Maste 
1095435933ddSDimitry Andric   if (py_return.IsValid()) {
1096435933ddSDimitry Andric     switch (return_type) {
10979f2f44ceSEd Maste     case eScriptReturnTypeCharPtr: // "char *"
10989f2f44ceSEd Maste     {
10999f2f44ceSEd Maste       const char format[3] = "s#";
11009f2f44ceSEd Maste       success = PyArg_Parse(py_return.get(), format, (char **)ret_value);
11019f2f44ceSEd Maste       break;
11029f2f44ceSEd Maste     }
1103435933ddSDimitry Andric     case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return ==
1104435933ddSDimitry Andric                                          // Py_None
11059f2f44ceSEd Maste     {
11069f2f44ceSEd Maste       const char format[3] = "z";
11079f2f44ceSEd Maste       success = PyArg_Parse(py_return.get(), format, (char **)ret_value);
11089f2f44ceSEd Maste       break;
11099f2f44ceSEd Maste     }
1110435933ddSDimitry Andric     case eScriptReturnTypeBool: {
11119f2f44ceSEd Maste       const char format[2] = "b";
11129f2f44ceSEd Maste       success = PyArg_Parse(py_return.get(), format, (bool *)ret_value);
11139f2f44ceSEd Maste       break;
11149f2f44ceSEd Maste     }
1115435933ddSDimitry Andric     case eScriptReturnTypeShortInt: {
11169f2f44ceSEd Maste       const char format[2] = "h";
11179f2f44ceSEd Maste       success = PyArg_Parse(py_return.get(), format, (short *)ret_value);
11189f2f44ceSEd Maste       break;
11199f2f44ceSEd Maste     }
1120435933ddSDimitry Andric     case eScriptReturnTypeShortIntUnsigned: {
11219f2f44ceSEd Maste       const char format[2] = "H";
1122435933ddSDimitry Andric       success =
1123435933ddSDimitry Andric           PyArg_Parse(py_return.get(), format, (unsigned short *)ret_value);
11249f2f44ceSEd Maste       break;
11259f2f44ceSEd Maste     }
1126435933ddSDimitry Andric     case eScriptReturnTypeInt: {
11279f2f44ceSEd Maste       const char format[2] = "i";
11289f2f44ceSEd Maste       success = PyArg_Parse(py_return.get(), format, (int *)ret_value);
11299f2f44ceSEd Maste       break;
11309f2f44ceSEd Maste     }
1131435933ddSDimitry Andric     case eScriptReturnTypeIntUnsigned: {
11329f2f44ceSEd Maste       const char format[2] = "I";
11334ba319b5SDimitry Andric       success = PyArg_Parse(py_return.get(), format, (unsigned int *)ret_value);
11349f2f44ceSEd Maste       break;
11359f2f44ceSEd Maste     }
1136435933ddSDimitry Andric     case eScriptReturnTypeLongInt: {
11379f2f44ceSEd Maste       const char format[2] = "l";
11389f2f44ceSEd Maste       success = PyArg_Parse(py_return.get(), format, (long *)ret_value);
11399f2f44ceSEd Maste       break;
11409f2f44ceSEd Maste     }
1141435933ddSDimitry Andric     case eScriptReturnTypeLongIntUnsigned: {
11429f2f44ceSEd Maste       const char format[2] = "k";
1143435933ddSDimitry Andric       success =
1144435933ddSDimitry Andric           PyArg_Parse(py_return.get(), format, (unsigned long *)ret_value);
11459f2f44ceSEd Maste       break;
11469f2f44ceSEd Maste     }
1147435933ddSDimitry Andric     case eScriptReturnTypeLongLong: {
11489f2f44ceSEd Maste       const char format[2] = "L";
11499f2f44ceSEd Maste       success = PyArg_Parse(py_return.get(), format, (long long *)ret_value);
11509f2f44ceSEd Maste       break;
11519f2f44ceSEd Maste     }
1152435933ddSDimitry Andric     case eScriptReturnTypeLongLongUnsigned: {
11539f2f44ceSEd Maste       const char format[2] = "K";
11544ba319b5SDimitry Andric       success =
11554ba319b5SDimitry Andric           PyArg_Parse(py_return.get(), format, (unsigned long long *)ret_value);
11569f2f44ceSEd Maste       break;
11579f2f44ceSEd Maste     }
1158435933ddSDimitry Andric     case eScriptReturnTypeFloat: {
11599f2f44ceSEd Maste       const char format[2] = "f";
11609f2f44ceSEd Maste       success = PyArg_Parse(py_return.get(), format, (float *)ret_value);
11619f2f44ceSEd Maste       break;
11629f2f44ceSEd Maste     }
1163435933ddSDimitry Andric     case eScriptReturnTypeDouble: {
11649f2f44ceSEd Maste       const char format[2] = "d";
11659f2f44ceSEd Maste       success = PyArg_Parse(py_return.get(), format, (double *)ret_value);
11669f2f44ceSEd Maste       break;
11679f2f44ceSEd Maste     }
1168435933ddSDimitry Andric     case eScriptReturnTypeChar: {
11699f2f44ceSEd Maste       const char format[2] = "c";
11709f2f44ceSEd Maste       success = PyArg_Parse(py_return.get(), format, (char *)ret_value);
11719f2f44ceSEd Maste       break;
11729f2f44ceSEd Maste     }
1173435933ddSDimitry Andric     case eScriptReturnTypeOpaqueObject: {
11749f2f44ceSEd Maste       success = true;
11759f2f44ceSEd Maste       PyObject *saved_value = py_return.get();
11769f2f44ceSEd Maste       Py_XINCREF(saved_value);
11779f2f44ceSEd Maste       *((PyObject **)ret_value) = saved_value;
11789f2f44ceSEd Maste       break;
11799f2f44ceSEd Maste     }
11809f2f44ceSEd Maste     }
11819f2f44ceSEd Maste 
11824ba319b5SDimitry Andric     ret_success = success;
11839f2f44ceSEd Maste   }
11849f2f44ceSEd Maste 
11859f2f44ceSEd Maste   py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
1186435933ddSDimitry Andric   if (py_error.IsValid()) {
11879f2f44ceSEd Maste     ret_success = false;
1188435933ddSDimitry Andric     if (options.GetMaskoutErrors()) {
11899f2f44ceSEd Maste       if (PyErr_GivenExceptionMatches(py_error.get(), PyExc_SyntaxError))
11909f2f44ceSEd Maste         PyErr_Print();
11919f2f44ceSEd Maste       PyErr_Clear();
11929f2f44ceSEd Maste     }
11939f2f44ceSEd Maste   }
11949f2f44ceSEd Maste 
11959f2f44ceSEd Maste   return ret_success;
11969f2f44ceSEd Maste }
11979f2f44ceSEd Maste 
ExecuteMultipleLines(const char * in_string,const ExecuteScriptOptions & options)11985517e702SDimitry Andric Status ScriptInterpreterPython::ExecuteMultipleLines(
1199435933ddSDimitry Andric     const char *in_string, const ExecuteScriptOptions &options) {
12005517e702SDimitry Andric   Status error;
12019f2f44ceSEd Maste 
1202435933ddSDimitry Andric   Locker locker(this, ScriptInterpreterPython::Locker::AcquireLock |
1203435933ddSDimitry Andric                           ScriptInterpreterPython::Locker::InitSession |
1204435933ddSDimitry Andric                           (options.GetSetLLDBGlobals()
1205435933ddSDimitry Andric                                ? ScriptInterpreterPython::Locker::InitGlobals
1206435933ddSDimitry Andric                                : 0) |
1207435933ddSDimitry Andric                           Locker::NoSTDIN,
1208435933ddSDimitry Andric                 ScriptInterpreterPython::Locker::FreeAcquiredLock |
1209435933ddSDimitry Andric                     ScriptInterpreterPython::Locker::TearDownSession);
12109f2f44ceSEd Maste 
12119f2f44ceSEd Maste   PythonObject return_value;
12129f2f44ceSEd Maste   PythonObject &main_module = GetMainModule();
1213435933ddSDimitry Andric   PythonDictionary globals(PyRefType::Borrowed,
1214435933ddSDimitry Andric                            PyModule_GetDict(main_module.get()));
12159f2f44ceSEd Maste   PythonObject py_error;
12169f2f44ceSEd Maste 
12179f2f44ceSEd Maste   PythonDictionary locals = GetSessionDictionary();
12189f2f44ceSEd Maste 
12199f2f44ceSEd Maste   if (!locals.IsValid())
1220435933ddSDimitry Andric     locals.Reset(
1221435933ddSDimitry Andric         PyRefType::Owned,
1222435933ddSDimitry Andric         PyObject_GetAttrString(globals.get(), m_dictionary_name.c_str()));
12239f2f44ceSEd Maste 
12249f2f44ceSEd Maste   if (!locals.IsValid())
12259f2f44ceSEd Maste     locals = globals;
12269f2f44ceSEd Maste 
12279f2f44ceSEd Maste   py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
12289f2f44ceSEd Maste   if (py_error.IsValid())
12299f2f44ceSEd Maste     PyErr_Clear();
12309f2f44ceSEd Maste 
1231435933ddSDimitry Andric   if (in_string != nullptr) {
12329f2f44ceSEd Maste     PythonObject code_object;
1233435933ddSDimitry Andric     code_object.Reset(PyRefType::Owned,
1234435933ddSDimitry Andric                       Py_CompileString(in_string, "temp.py", Py_file_input));
12359f2f44ceSEd Maste 
1236435933ddSDimitry Andric     if (code_object.IsValid()) {
1237435933ddSDimitry Andric // In Python 2.x, PyEval_EvalCode takes a PyCodeObject, but in Python 3.x, it
12384ba319b5SDimitry Andric // takes a PyObject.  They are convertible (hence the function
12394ba319b5SDimitry Andric // PyCode_Check(PyObject*), so we have to do the cast for Python 2.x
12409f2f44ceSEd Maste #if PY_MAJOR_VERSION >= 3
12419f2f44ceSEd Maste       PyObject *py_code_obj = code_object.get();
12429f2f44ceSEd Maste #else
1243435933ddSDimitry Andric       PyCodeObject *py_code_obj =
1244435933ddSDimitry Andric           reinterpret_cast<PyCodeObject *>(code_object.get());
12459f2f44ceSEd Maste #endif
1246435933ddSDimitry Andric       return_value.Reset(
1247435933ddSDimitry Andric           PyRefType::Owned,
1248435933ddSDimitry Andric           PyEval_EvalCode(py_code_obj, globals.get(), locals.get()));
12499f2f44ceSEd Maste     }
12509f2f44ceSEd Maste   }
12519f2f44ceSEd Maste 
12529f2f44ceSEd Maste   PythonExceptionState exception_state(!options.GetMaskoutErrors());
12539f2f44ceSEd Maste   if (exception_state.IsError())
12549f2f44ceSEd Maste     error.SetErrorString(exception_state.Format().c_str());
12559f2f44ceSEd Maste 
12569f2f44ceSEd Maste   return error;
12579f2f44ceSEd Maste }
12589f2f44ceSEd Maste 
CollectDataForBreakpointCommandCallback(std::vector<BreakpointOptions * > & bp_options_vec,CommandReturnObject & result)1259435933ddSDimitry Andric void ScriptInterpreterPython::CollectDataForBreakpointCommandCallback(
1260435933ddSDimitry Andric     std::vector<BreakpointOptions *> &bp_options_vec,
1261435933ddSDimitry Andric     CommandReturnObject &result) {
12629f2f44ceSEd Maste   m_active_io_handler = eIOHandlerBreakpoint;
1263435933ddSDimitry Andric   m_interpreter.GetPythonCommandsFromIOHandler("    ", *this, true,
1264435933ddSDimitry Andric                                                &bp_options_vec);
12659f2f44ceSEd Maste }
12669f2f44ceSEd Maste 
CollectDataForWatchpointCommandCallback(WatchpointOptions * wp_options,CommandReturnObject & result)1267435933ddSDimitry Andric void ScriptInterpreterPython::CollectDataForWatchpointCommandCallback(
1268435933ddSDimitry Andric     WatchpointOptions *wp_options, CommandReturnObject &result) {
12699f2f44ceSEd Maste   m_active_io_handler = eIOHandlerWatchpoint;
12709f2f44ceSEd Maste   m_interpreter.GetPythonCommandsFromIOHandler("    ", *this, true, wp_options);
12719f2f44ceSEd Maste }
12729f2f44ceSEd Maste 
SetBreakpointCommandCallbackFunction(BreakpointOptions * bp_options,const char * function_name)1273435933ddSDimitry Andric void ScriptInterpreterPython::SetBreakpointCommandCallbackFunction(
1274435933ddSDimitry Andric     BreakpointOptions *bp_options, const char *function_name) {
12759f2f44ceSEd Maste   // For now just cons up a oneliner that calls the provided function.
12769f2f44ceSEd Maste   std::string oneliner("return ");
12779f2f44ceSEd Maste   oneliner += function_name;
12789f2f44ceSEd Maste   oneliner += "(frame, bp_loc, internal_dict)";
1279435933ddSDimitry Andric   m_interpreter.GetScriptInterpreter()->SetBreakpointCommandCallback(
1280435933ddSDimitry Andric       bp_options, oneliner.c_str());
1281435933ddSDimitry Andric }
1282435933ddSDimitry Andric 
SetBreakpointCommandCallback(BreakpointOptions * bp_options,std::unique_ptr<BreakpointOptions::CommandData> & cmd_data_up)12835517e702SDimitry Andric Status ScriptInterpreterPython::SetBreakpointCommandCallback(
1284435933ddSDimitry Andric     BreakpointOptions *bp_options,
1285435933ddSDimitry Andric     std::unique_ptr<BreakpointOptions::CommandData> &cmd_data_up) {
12865517e702SDimitry Andric   Status error;
1287435933ddSDimitry Andric   error = GenerateBreakpointCommandCallbackData(cmd_data_up->user_source,
1288435933ddSDimitry Andric                                                 cmd_data_up->script_source);
1289435933ddSDimitry Andric   if (error.Fail()) {
1290435933ddSDimitry Andric     return error;
1291435933ddSDimitry Andric   }
1292435933ddSDimitry Andric   auto baton_sp =
1293435933ddSDimitry Andric       std::make_shared<BreakpointOptions::CommandBaton>(std::move(cmd_data_up));
1294435933ddSDimitry Andric   bp_options->SetCallback(ScriptInterpreterPython::BreakpointCallbackFunction,
1295435933ddSDimitry Andric                           baton_sp);
1296435933ddSDimitry Andric   return error;
12979f2f44ceSEd Maste }
12989f2f44ceSEd Maste 
12999f2f44ceSEd Maste // Set a Python one-liner as the callback for the breakpoint.
SetBreakpointCommandCallback(BreakpointOptions * bp_options,const char * command_body_text)13005517e702SDimitry Andric Status ScriptInterpreterPython::SetBreakpointCommandCallback(
1301435933ddSDimitry Andric     BreakpointOptions *bp_options, const char *command_body_text) {
1302435933ddSDimitry Andric   auto data_ap = llvm::make_unique<CommandDataPython>();
13039f2f44ceSEd Maste 
1304435933ddSDimitry Andric   // Split the command_body_text into lines, and pass that to
13054ba319b5SDimitry Andric   // GenerateBreakpointCommandCallbackData.  That will wrap the body in an
13064ba319b5SDimitry Andric   // auto-generated function, and return the function name in script_source.
13074ba319b5SDimitry Andric   // That is what the callback will actually invoke.
13089f2f44ceSEd Maste 
13099f2f44ceSEd Maste   data_ap->user_source.SplitIntoLines(command_body_text);
13105517e702SDimitry Andric   Status error = GenerateBreakpointCommandCallbackData(data_ap->user_source,
1311435933ddSDimitry Andric                                                        data_ap->script_source);
1312435933ddSDimitry Andric   if (error.Success()) {
1313435933ddSDimitry Andric     auto baton_sp =
1314435933ddSDimitry Andric         std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_ap));
1315435933ddSDimitry Andric     bp_options->SetCallback(ScriptInterpreterPython::BreakpointCallbackFunction,
1316435933ddSDimitry Andric                             baton_sp);
13179f2f44ceSEd Maste     return error;
1318435933ddSDimitry Andric   } else
13199f2f44ceSEd Maste     return error;
13209f2f44ceSEd Maste }
13219f2f44ceSEd Maste 
13229f2f44ceSEd Maste // Set a Python one-liner as the callback for the watchpoint.
SetWatchpointCommandCallback(WatchpointOptions * wp_options,const char * oneliner)1323435933ddSDimitry Andric void ScriptInterpreterPython::SetWatchpointCommandCallback(
1324435933ddSDimitry Andric     WatchpointOptions *wp_options, const char *oneliner) {
1325435933ddSDimitry Andric   auto data_ap = llvm::make_unique<WatchpointOptions::CommandData>();
13269f2f44ceSEd Maste 
13279f2f44ceSEd Maste   // It's necessary to set both user_source and script_source to the oneliner.
1328435933ddSDimitry Andric   // The former is used to generate callback description (as in watchpoint
13294ba319b5SDimitry Andric   // command list) while the latter is used for Python to interpret during the
13304ba319b5SDimitry Andric   // actual callback.
13319f2f44ceSEd Maste 
13329f2f44ceSEd Maste   data_ap->user_source.AppendString(oneliner);
13339f2f44ceSEd Maste   data_ap->script_source.assign(oneliner);
13349f2f44ceSEd Maste 
1335435933ddSDimitry Andric   if (GenerateWatchpointCommandCallbackData(data_ap->user_source,
1336435933ddSDimitry Andric                                             data_ap->script_source)) {
1337435933ddSDimitry Andric     auto baton_sp =
1338435933ddSDimitry Andric         std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_ap));
1339435933ddSDimitry Andric     wp_options->SetCallback(ScriptInterpreterPython::WatchpointCallbackFunction,
1340435933ddSDimitry Andric                             baton_sp);
13419f2f44ceSEd Maste   }
13429f2f44ceSEd Maste 
13439f2f44ceSEd Maste   return;
13449f2f44ceSEd Maste }
13459f2f44ceSEd Maste 
ExportFunctionDefinitionToInterpreter(StringList & function_def)13465517e702SDimitry Andric Status ScriptInterpreterPython::ExportFunctionDefinitionToInterpreter(
1347435933ddSDimitry Andric     StringList &function_def) {
13489f2f44ceSEd Maste   // Convert StringList to one long, newline delimited, const char *.
13499f2f44ceSEd Maste   std::string function_def_string(function_def.CopyList());
13509f2f44ceSEd Maste 
13515517e702SDimitry Andric   Status error = ExecuteMultipleLines(
1352435933ddSDimitry Andric       function_def_string.c_str(),
1353435933ddSDimitry Andric       ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false));
13549f2f44ceSEd Maste   return error;
13559f2f44ceSEd Maste }
13569f2f44ceSEd Maste 
GenerateFunction(const char * signature,const StringList & input)13575517e702SDimitry Andric Status ScriptInterpreterPython::GenerateFunction(const char *signature,
1358435933ddSDimitry Andric                                                  const StringList &input) {
13595517e702SDimitry Andric   Status error;
13609f2f44ceSEd Maste   int num_lines = input.GetSize();
1361435933ddSDimitry Andric   if (num_lines == 0) {
13629f2f44ceSEd Maste     error.SetErrorString("No input data.");
13639f2f44ceSEd Maste     return error;
13649f2f44ceSEd Maste   }
13659f2f44ceSEd Maste 
1366435933ddSDimitry Andric   if (!signature || *signature == 0) {
13679f2f44ceSEd Maste     error.SetErrorString("No output function name.");
13689f2f44ceSEd Maste     return error;
13699f2f44ceSEd Maste   }
13709f2f44ceSEd Maste 
13719f2f44ceSEd Maste   StreamString sstr;
13729f2f44ceSEd Maste   StringList auto_generated_function;
13739f2f44ceSEd Maste   auto_generated_function.AppendString(signature);
1374435933ddSDimitry Andric   auto_generated_function.AppendString(
1375435933ddSDimitry Andric       "     global_dict = globals()"); // Grab the global dictionary
1376435933ddSDimitry Andric   auto_generated_function.AppendString(
1377435933ddSDimitry Andric       "     new_keys = internal_dict.keys()"); // Make a list of keys in the
1378435933ddSDimitry Andric                                                // session dict
1379435933ddSDimitry Andric   auto_generated_function.AppendString(
1380435933ddSDimitry Andric       "     old_keys = global_dict.keys()"); // Save list of keys in global dict
1381435933ddSDimitry Andric   auto_generated_function.AppendString(
1382435933ddSDimitry Andric       "     global_dict.update (internal_dict)"); // Add the session dictionary
1383435933ddSDimitry Andric                                                   // to the
13849f2f44ceSEd Maste   // global dictionary.
13859f2f44ceSEd Maste 
13869f2f44ceSEd Maste   // Wrap everything up inside the function, increasing the indentation.
13879f2f44ceSEd Maste 
13889f2f44ceSEd Maste   auto_generated_function.AppendString("     if True:");
1389435933ddSDimitry Andric   for (int i = 0; i < num_lines; ++i) {
13909f2f44ceSEd Maste     sstr.Clear();
13919f2f44ceSEd Maste     sstr.Printf("       %s", input.GetStringAtIndex(i));
13929f2f44ceSEd Maste     auto_generated_function.AppendString(sstr.GetData());
13939f2f44ceSEd Maste   }
1394435933ddSDimitry Andric   auto_generated_function.AppendString(
1395435933ddSDimitry Andric       "     for key in new_keys:"); // Iterate over all the keys from session
1396435933ddSDimitry Andric                                     // dict
1397435933ddSDimitry Andric   auto_generated_function.AppendString(
1398435933ddSDimitry Andric       "         internal_dict[key] = global_dict[key]"); // Update session dict
1399435933ddSDimitry Andric                                                          // values
1400435933ddSDimitry Andric   auto_generated_function.AppendString(
1401435933ddSDimitry Andric       "         if key not in old_keys:"); // If key was not originally in
1402435933ddSDimitry Andric                                            // global dict
1403435933ddSDimitry Andric   auto_generated_function.AppendString(
1404435933ddSDimitry Andric       "             del global_dict[key]"); //  ...then remove key/value from
1405435933ddSDimitry Andric                                             //  global dict
14069f2f44ceSEd Maste 
14079f2f44ceSEd Maste   // Verify that the results are valid Python.
14089f2f44ceSEd Maste 
14099f2f44ceSEd Maste   error = ExportFunctionDefinitionToInterpreter(auto_generated_function);
14109f2f44ceSEd Maste 
14119f2f44ceSEd Maste   return error;
14129f2f44ceSEd Maste }
14139f2f44ceSEd Maste 
GenerateTypeScriptFunction(StringList & user_input,std::string & output,const void * name_token)1414435933ddSDimitry Andric bool ScriptInterpreterPython::GenerateTypeScriptFunction(
1415435933ddSDimitry Andric     StringList &user_input, std::string &output, const void *name_token) {
14169f2f44ceSEd Maste   static uint32_t num_created_functions = 0;
14179f2f44ceSEd Maste   user_input.RemoveBlankLines();
14189f2f44ceSEd Maste   StreamString sstr;
14199f2f44ceSEd Maste 
14209f2f44ceSEd Maste   // Check to see if we have any data; if not, just return.
14219f2f44ceSEd Maste   if (user_input.GetSize() == 0)
14229f2f44ceSEd Maste     return false;
14239f2f44ceSEd Maste 
1424435933ddSDimitry Andric   // Take what the user wrote, wrap it all up inside one big auto-generated
14254ba319b5SDimitry Andric   // Python function, passing in the ValueObject as parameter to the function.
14269f2f44ceSEd Maste 
1427435933ddSDimitry Andric   std::string auto_generated_function_name(
1428435933ddSDimitry Andric       GenerateUniqueName("lldb_autogen_python_type_print_func",
1429435933ddSDimitry Andric                          num_created_functions, name_token));
1430435933ddSDimitry Andric   sstr.Printf("def %s (valobj, internal_dict):",
1431435933ddSDimitry Andric               auto_generated_function_name.c_str());
14329f2f44ceSEd Maste 
14339f2f44ceSEd Maste   if (!GenerateFunction(sstr.GetData(), user_input).Success())
14349f2f44ceSEd Maste     return false;
14359f2f44ceSEd Maste 
14369f2f44ceSEd Maste   // Store the name of the auto-generated function to be called.
14379f2f44ceSEd Maste   output.assign(auto_generated_function_name);
14389f2f44ceSEd Maste   return true;
14399f2f44ceSEd Maste }
14409f2f44ceSEd Maste 
GenerateScriptAliasFunction(StringList & user_input,std::string & output)1441435933ddSDimitry Andric bool ScriptInterpreterPython::GenerateScriptAliasFunction(
1442435933ddSDimitry Andric     StringList &user_input, std::string &output) {
14439f2f44ceSEd Maste   static uint32_t num_created_functions = 0;
14449f2f44ceSEd Maste   user_input.RemoveBlankLines();
14459f2f44ceSEd Maste   StreamString sstr;
14469f2f44ceSEd Maste 
14479f2f44ceSEd Maste   // Check to see if we have any data; if not, just return.
14489f2f44ceSEd Maste   if (user_input.GetSize() == 0)
14499f2f44ceSEd Maste     return false;
14509f2f44ceSEd Maste 
1451435933ddSDimitry Andric   std::string auto_generated_function_name(GenerateUniqueName(
1452435933ddSDimitry Andric       "lldb_autogen_python_cmd_alias_func", num_created_functions));
14539f2f44ceSEd Maste 
1454435933ddSDimitry Andric   sstr.Printf("def %s (debugger, args, result, internal_dict):",
1455435933ddSDimitry Andric               auto_generated_function_name.c_str());
14569f2f44ceSEd Maste 
14579f2f44ceSEd Maste   if (!GenerateFunction(sstr.GetData(), user_input).Success())
14589f2f44ceSEd Maste     return false;
14599f2f44ceSEd Maste 
14609f2f44ceSEd Maste   // Store the name of the auto-generated function to be called.
14619f2f44ceSEd Maste   output.assign(auto_generated_function_name);
14629f2f44ceSEd Maste   return true;
14639f2f44ceSEd Maste }
14649f2f44ceSEd Maste 
GenerateTypeSynthClass(StringList & user_input,std::string & output,const void * name_token)1465435933ddSDimitry Andric bool ScriptInterpreterPython::GenerateTypeSynthClass(StringList &user_input,
1466435933ddSDimitry Andric                                                      std::string &output,
1467435933ddSDimitry Andric                                                      const void *name_token) {
14689f2f44ceSEd Maste   static uint32_t num_created_classes = 0;
14699f2f44ceSEd Maste   user_input.RemoveBlankLines();
14709f2f44ceSEd Maste   int num_lines = user_input.GetSize();
14719f2f44ceSEd Maste   StreamString sstr;
14729f2f44ceSEd Maste 
14739f2f44ceSEd Maste   // Check to see if we have any data; if not, just return.
14749f2f44ceSEd Maste   if (user_input.GetSize() == 0)
14759f2f44ceSEd Maste     return false;
14769f2f44ceSEd Maste 
14779f2f44ceSEd Maste   // Wrap all user input into a Python class
14789f2f44ceSEd Maste 
1479435933ddSDimitry Andric   std::string auto_generated_class_name(GenerateUniqueName(
1480435933ddSDimitry Andric       "lldb_autogen_python_type_synth_class", num_created_classes, name_token));
14819f2f44ceSEd Maste 
14829f2f44ceSEd Maste   StringList auto_generated_class;
14839f2f44ceSEd Maste 
14849f2f44ceSEd Maste   // Create the function name & definition string.
14859f2f44ceSEd Maste 
14869f2f44ceSEd Maste   sstr.Printf("class %s:", auto_generated_class_name.c_str());
1487435933ddSDimitry Andric   auto_generated_class.AppendString(sstr.GetString());
14889f2f44ceSEd Maste 
14894ba319b5SDimitry Andric   // Wrap everything up inside the class, increasing the indentation. we don't
14904ba319b5SDimitry Andric   // need to play any fancy indentation tricks here because there is no
14919f2f44ceSEd Maste   // surrounding code whose indentation we need to honor
1492435933ddSDimitry Andric   for (int i = 0; i < num_lines; ++i) {
14939f2f44ceSEd Maste     sstr.Clear();
14949f2f44ceSEd Maste     sstr.Printf("     %s", user_input.GetStringAtIndex(i));
1495435933ddSDimitry Andric     auto_generated_class.AppendString(sstr.GetString());
14969f2f44ceSEd Maste   }
14979f2f44ceSEd Maste 
14984ba319b5SDimitry Andric   // Verify that the results are valid Python. (even though the method is
14994ba319b5SDimitry Andric   // ExportFunctionDefinitionToInterpreter, a class will actually be exported)
15009f2f44ceSEd Maste   // (TODO: rename that method to ExportDefinitionToInterpreter)
15019f2f44ceSEd Maste   if (!ExportFunctionDefinitionToInterpreter(auto_generated_class).Success())
15029f2f44ceSEd Maste     return false;
15039f2f44ceSEd Maste 
15049f2f44ceSEd Maste   // Store the name of the auto-generated class
15059f2f44ceSEd Maste 
15069f2f44ceSEd Maste   output.assign(auto_generated_class_name);
15079f2f44ceSEd Maste   return true;
15089f2f44ceSEd Maste }
15099f2f44ceSEd Maste 
CreateFrameRecognizer(const char * class_name)1510*b5893f02SDimitry Andric StructuredData::GenericSP ScriptInterpreterPython::CreateFrameRecognizer(
1511*b5893f02SDimitry Andric     const char *class_name) {
1512*b5893f02SDimitry Andric   if (class_name == nullptr || class_name[0] == '\0')
1513*b5893f02SDimitry Andric     return StructuredData::GenericSP();
1514*b5893f02SDimitry Andric 
1515*b5893f02SDimitry Andric   void *ret_val;
1516*b5893f02SDimitry Andric 
1517*b5893f02SDimitry Andric   {
1518*b5893f02SDimitry Andric     Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN,
1519*b5893f02SDimitry Andric                    Locker::FreeLock);
1520*b5893f02SDimitry Andric     ret_val =
1521*b5893f02SDimitry Andric         g_swig_create_frame_recognizer(class_name, m_dictionary_name.c_str());
1522*b5893f02SDimitry Andric   }
1523*b5893f02SDimitry Andric 
1524*b5893f02SDimitry Andric   return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
1525*b5893f02SDimitry Andric }
1526*b5893f02SDimitry Andric 
GetRecognizedArguments(const StructuredData::ObjectSP & os_plugin_object_sp,lldb::StackFrameSP frame_sp)1527*b5893f02SDimitry Andric lldb::ValueObjectListSP ScriptInterpreterPython::GetRecognizedArguments(
1528*b5893f02SDimitry Andric     const StructuredData::ObjectSP &os_plugin_object_sp,
1529*b5893f02SDimitry Andric     lldb::StackFrameSP frame_sp) {
1530*b5893f02SDimitry Andric   Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
1531*b5893f02SDimitry Andric 
1532*b5893f02SDimitry Andric   if (!os_plugin_object_sp) return ValueObjectListSP();
1533*b5893f02SDimitry Andric 
1534*b5893f02SDimitry Andric   StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
1535*b5893f02SDimitry Andric   if (!generic) return nullptr;
1536*b5893f02SDimitry Andric 
1537*b5893f02SDimitry Andric   PythonObject implementor(PyRefType::Borrowed,
1538*b5893f02SDimitry Andric                            (PyObject *)generic->GetValue());
1539*b5893f02SDimitry Andric 
1540*b5893f02SDimitry Andric   if (!implementor.IsAllocated()) return ValueObjectListSP();
1541*b5893f02SDimitry Andric 
1542*b5893f02SDimitry Andric   PythonObject py_return(
1543*b5893f02SDimitry Andric       PyRefType::Owned,
1544*b5893f02SDimitry Andric       (PyObject *)g_swig_get_recognized_arguments(implementor.get(), frame_sp));
1545*b5893f02SDimitry Andric 
1546*b5893f02SDimitry Andric   // if it fails, print the error but otherwise go on
1547*b5893f02SDimitry Andric   if (PyErr_Occurred()) {
1548*b5893f02SDimitry Andric     PyErr_Print();
1549*b5893f02SDimitry Andric     PyErr_Clear();
1550*b5893f02SDimitry Andric   }
1551*b5893f02SDimitry Andric   if (py_return.get()) {
1552*b5893f02SDimitry Andric     PythonList result_list(PyRefType::Borrowed, py_return.get());
1553*b5893f02SDimitry Andric     ValueObjectListSP result = ValueObjectListSP(new ValueObjectList());
1554*b5893f02SDimitry Andric     for (size_t i = 0; i < result_list.GetSize(); i++) {
1555*b5893f02SDimitry Andric       PyObject *item = result_list.GetItemAtIndex(i).get();
1556*b5893f02SDimitry Andric       lldb::SBValue *sb_value_ptr =
1557*b5893f02SDimitry Andric           (lldb::SBValue *)g_swig_cast_to_sbvalue(item);
1558*b5893f02SDimitry Andric       auto valobj_sp = g_swig_get_valobj_sp_from_sbvalue(sb_value_ptr);
1559*b5893f02SDimitry Andric       if (valobj_sp) result->Append(valobj_sp);
1560*b5893f02SDimitry Andric     }
1561*b5893f02SDimitry Andric     return result;
1562*b5893f02SDimitry Andric   }
1563*b5893f02SDimitry Andric   return ValueObjectListSP();
1564*b5893f02SDimitry Andric }
1565*b5893f02SDimitry Andric 
OSPlugin_CreatePluginObject(const char * class_name,lldb::ProcessSP process_sp)1566435933ddSDimitry Andric StructuredData::GenericSP ScriptInterpreterPython::OSPlugin_CreatePluginObject(
1567435933ddSDimitry Andric     const char *class_name, lldb::ProcessSP process_sp) {
15689f2f44ceSEd Maste   if (class_name == nullptr || class_name[0] == '\0')
15699f2f44ceSEd Maste     return StructuredData::GenericSP();
15709f2f44ceSEd Maste 
15719f2f44ceSEd Maste   if (!process_sp)
15729f2f44ceSEd Maste     return StructuredData::GenericSP();
15739f2f44ceSEd Maste 
15749f2f44ceSEd Maste   void *ret_val;
15759f2f44ceSEd Maste 
15769f2f44ceSEd Maste   {
1577435933ddSDimitry Andric     Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN,
15789f2f44ceSEd Maste                    Locker::FreeLock);
1579435933ddSDimitry Andric     ret_val = g_swig_create_os_plugin(class_name, m_dictionary_name.c_str(),
15809f2f44ceSEd Maste                                       process_sp);
15819f2f44ceSEd Maste   }
15829f2f44ceSEd Maste 
15839f2f44ceSEd Maste   return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
15849f2f44ceSEd Maste }
15859f2f44ceSEd Maste 
OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp)1586435933ddSDimitry Andric StructuredData::DictionarySP ScriptInterpreterPython::OSPlugin_RegisterInfo(
1587435933ddSDimitry Andric     StructuredData::ObjectSP os_plugin_object_sp) {
1588435933ddSDimitry Andric   Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
15899f2f44ceSEd Maste 
15909f2f44ceSEd Maste   static char callee_name[] = "get_register_info";
15919f2f44ceSEd Maste 
15929f2f44ceSEd Maste   if (!os_plugin_object_sp)
15939f2f44ceSEd Maste     return StructuredData::DictionarySP();
15949f2f44ceSEd Maste 
15959f2f44ceSEd Maste   StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
15969f2f44ceSEd Maste   if (!generic)
15979f2f44ceSEd Maste     return nullptr;
15989f2f44ceSEd Maste 
1599435933ddSDimitry Andric   PythonObject implementor(PyRefType::Borrowed,
1600435933ddSDimitry Andric                            (PyObject *)generic->GetValue());
16019f2f44ceSEd Maste 
16029f2f44ceSEd Maste   if (!implementor.IsAllocated())
16039f2f44ceSEd Maste     return StructuredData::DictionarySP();
16049f2f44ceSEd Maste 
1605435933ddSDimitry Andric   PythonObject pmeth(PyRefType::Owned,
1606435933ddSDimitry Andric                      PyObject_GetAttrString(implementor.get(), callee_name));
16079f2f44ceSEd Maste 
16089f2f44ceSEd Maste   if (PyErr_Occurred())
16099f2f44ceSEd Maste     PyErr_Clear();
16109f2f44ceSEd Maste 
16119f2f44ceSEd Maste   if (!pmeth.IsAllocated())
16129f2f44ceSEd Maste     return StructuredData::DictionarySP();
16139f2f44ceSEd Maste 
1614435933ddSDimitry Andric   if (PyCallable_Check(pmeth.get()) == 0) {
16159f2f44ceSEd Maste     if (PyErr_Occurred())
16169f2f44ceSEd Maste       PyErr_Clear();
16179f2f44ceSEd Maste 
16189f2f44ceSEd Maste     return StructuredData::DictionarySP();
16199f2f44ceSEd Maste   }
16209f2f44ceSEd Maste 
16219f2f44ceSEd Maste   if (PyErr_Occurred())
16229f2f44ceSEd Maste     PyErr_Clear();
16239f2f44ceSEd Maste 
16249f2f44ceSEd Maste   // right now we know this function exists and is callable..
1625435933ddSDimitry Andric   PythonObject py_return(
1626435933ddSDimitry Andric       PyRefType::Owned,
1627435933ddSDimitry Andric       PyObject_CallMethod(implementor.get(), callee_name, nullptr));
16289f2f44ceSEd Maste 
16299f2f44ceSEd Maste   // if it fails, print the error but otherwise go on
1630435933ddSDimitry Andric   if (PyErr_Occurred()) {
16319f2f44ceSEd Maste     PyErr_Print();
16329f2f44ceSEd Maste     PyErr_Clear();
16339f2f44ceSEd Maste   }
1634435933ddSDimitry Andric   if (py_return.get()) {
16359f2f44ceSEd Maste     PythonDictionary result_dict(PyRefType::Borrowed, py_return.get());
16369f2f44ceSEd Maste     return result_dict.CreateStructuredDictionary();
16379f2f44ceSEd Maste   }
16384bb0738eSEd Maste   return StructuredData::DictionarySP();
16394bb0738eSEd Maste }
16409f2f44ceSEd Maste 
OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp)1641435933ddSDimitry Andric StructuredData::ArraySP ScriptInterpreterPython::OSPlugin_ThreadsInfo(
1642435933ddSDimitry Andric     StructuredData::ObjectSP os_plugin_object_sp) {
1643435933ddSDimitry Andric   Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
16449f2f44ceSEd Maste 
16459f2f44ceSEd Maste   static char callee_name[] = "get_thread_info";
16469f2f44ceSEd Maste 
16479f2f44ceSEd Maste   if (!os_plugin_object_sp)
16489f2f44ceSEd Maste     return StructuredData::ArraySP();
16499f2f44ceSEd Maste 
16509f2f44ceSEd Maste   StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
16519f2f44ceSEd Maste   if (!generic)
16529f2f44ceSEd Maste     return nullptr;
16539f2f44ceSEd Maste 
1654435933ddSDimitry Andric   PythonObject implementor(PyRefType::Borrowed,
1655435933ddSDimitry Andric                            (PyObject *)generic->GetValue());
16569f2f44ceSEd Maste 
16579f2f44ceSEd Maste   if (!implementor.IsAllocated())
16589f2f44ceSEd Maste     return StructuredData::ArraySP();
16599f2f44ceSEd Maste 
1660435933ddSDimitry Andric   PythonObject pmeth(PyRefType::Owned,
1661435933ddSDimitry Andric                      PyObject_GetAttrString(implementor.get(), callee_name));
16629f2f44ceSEd Maste 
16639f2f44ceSEd Maste   if (PyErr_Occurred())
16649f2f44ceSEd Maste     PyErr_Clear();
16659f2f44ceSEd Maste 
16669f2f44ceSEd Maste   if (!pmeth.IsAllocated())
16679f2f44ceSEd Maste     return StructuredData::ArraySP();
16689f2f44ceSEd Maste 
1669435933ddSDimitry Andric   if (PyCallable_Check(pmeth.get()) == 0) {
16709f2f44ceSEd Maste     if (PyErr_Occurred())
16719f2f44ceSEd Maste       PyErr_Clear();
16729f2f44ceSEd Maste 
16739f2f44ceSEd Maste     return StructuredData::ArraySP();
16749f2f44ceSEd Maste   }
16759f2f44ceSEd Maste 
16769f2f44ceSEd Maste   if (PyErr_Occurred())
16779f2f44ceSEd Maste     PyErr_Clear();
16789f2f44ceSEd Maste 
16799f2f44ceSEd Maste   // right now we know this function exists and is callable..
1680435933ddSDimitry Andric   PythonObject py_return(
1681435933ddSDimitry Andric       PyRefType::Owned,
1682435933ddSDimitry Andric       PyObject_CallMethod(implementor.get(), callee_name, nullptr));
16839f2f44ceSEd Maste 
16849f2f44ceSEd Maste   // if it fails, print the error but otherwise go on
1685435933ddSDimitry Andric   if (PyErr_Occurred()) {
16869f2f44ceSEd Maste     PyErr_Print();
16879f2f44ceSEd Maste     PyErr_Clear();
16889f2f44ceSEd Maste   }
16899f2f44ceSEd Maste 
1690435933ddSDimitry Andric   if (py_return.get()) {
16919f2f44ceSEd Maste     PythonList result_list(PyRefType::Borrowed, py_return.get());
16929f2f44ceSEd Maste     return result_list.CreateStructuredArray();
16939f2f44ceSEd Maste   }
16944bb0738eSEd Maste   return StructuredData::ArraySP();
16954bb0738eSEd Maste }
16969f2f44ceSEd Maste 
16979f2f44ceSEd Maste // GetPythonValueFormatString provides a system independent type safe way to
16989f2f44ceSEd Maste // convert a variable's type into a python value format. Python value formats
16994ba319b5SDimitry Andric // are defined in terms of builtin C types and could change from system to as
17004ba319b5SDimitry Andric // the underlying typedef for uint* types, size_t, off_t and other values
17019f2f44ceSEd Maste // change.
17029f2f44ceSEd Maste 
170395ec533aSDimitry Andric template <typename T> const char *GetPythonValueFormatString(T t);
GetPythonValueFormatString(char *)17049f2f44ceSEd Maste template <> const char *GetPythonValueFormatString(char *) { return "s"; }
GetPythonValueFormatString(char)17059f2f44ceSEd Maste template <> const char *GetPythonValueFormatString(char) { return "b"; }
GetPythonValueFormatString(unsigned char)1706435933ddSDimitry Andric template <> const char *GetPythonValueFormatString(unsigned char) {
1707435933ddSDimitry Andric   return "B";
1708435933ddSDimitry Andric }
GetPythonValueFormatString(short)17099f2f44ceSEd Maste template <> const char *GetPythonValueFormatString(short) { return "h"; }
GetPythonValueFormatString(unsigned short)1710435933ddSDimitry Andric template <> const char *GetPythonValueFormatString(unsigned short) {
1711435933ddSDimitry Andric   return "H";
1712435933ddSDimitry Andric }
GetPythonValueFormatString(int)17139f2f44ceSEd Maste template <> const char *GetPythonValueFormatString(int) { return "i"; }
GetPythonValueFormatString(unsigned int)17149f2f44ceSEd Maste template <> const char *GetPythonValueFormatString(unsigned int) { return "I"; }
GetPythonValueFormatString(long)17159f2f44ceSEd Maste template <> const char *GetPythonValueFormatString(long) { return "l"; }
GetPythonValueFormatString(unsigned long)1716435933ddSDimitry Andric template <> const char *GetPythonValueFormatString(unsigned long) {
1717435933ddSDimitry Andric   return "k";
1718435933ddSDimitry Andric }
GetPythonValueFormatString(long long)17199f2f44ceSEd Maste template <> const char *GetPythonValueFormatString(long long) { return "L"; }
GetPythonValueFormatString(unsigned long long)1720435933ddSDimitry Andric template <> const char *GetPythonValueFormatString(unsigned long long) {
1721435933ddSDimitry Andric   return "K";
1722435933ddSDimitry Andric }
GetPythonValueFormatString(float t)17239f2f44ceSEd Maste template <> const char *GetPythonValueFormatString(float t) { return "f"; }
GetPythonValueFormatString(double t)17249f2f44ceSEd Maste template <> const char *GetPythonValueFormatString(double t) { return "d"; }
17259f2f44ceSEd Maste 
OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp,lldb::tid_t tid)1726435933ddSDimitry Andric StructuredData::StringSP ScriptInterpreterPython::OSPlugin_RegisterContextData(
1727435933ddSDimitry Andric     StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid) {
1728435933ddSDimitry Andric   Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
17299f2f44ceSEd Maste 
17309f2f44ceSEd Maste   static char callee_name[] = "get_register_data";
1731435933ddSDimitry Andric   static char *param_format =
1732435933ddSDimitry Andric       const_cast<char *>(GetPythonValueFormatString(tid));
17339f2f44ceSEd Maste 
17349f2f44ceSEd Maste   if (!os_plugin_object_sp)
17359f2f44ceSEd Maste     return StructuredData::StringSP();
17369f2f44ceSEd Maste 
17379f2f44ceSEd Maste   StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
17389f2f44ceSEd Maste   if (!generic)
17399f2f44ceSEd Maste     return nullptr;
1740435933ddSDimitry Andric   PythonObject implementor(PyRefType::Borrowed,
1741435933ddSDimitry Andric                            (PyObject *)generic->GetValue());
17429f2f44ceSEd Maste 
17439f2f44ceSEd Maste   if (!implementor.IsAllocated())
17449f2f44ceSEd Maste     return StructuredData::StringSP();
17459f2f44ceSEd Maste 
1746435933ddSDimitry Andric   PythonObject pmeth(PyRefType::Owned,
1747435933ddSDimitry Andric                      PyObject_GetAttrString(implementor.get(), callee_name));
17489f2f44ceSEd Maste 
17499f2f44ceSEd Maste   if (PyErr_Occurred())
17509f2f44ceSEd Maste     PyErr_Clear();
17519f2f44ceSEd Maste 
17529f2f44ceSEd Maste   if (!pmeth.IsAllocated())
17539f2f44ceSEd Maste     return StructuredData::StringSP();
17549f2f44ceSEd Maste 
1755435933ddSDimitry Andric   if (PyCallable_Check(pmeth.get()) == 0) {
17569f2f44ceSEd Maste     if (PyErr_Occurred())
17579f2f44ceSEd Maste       PyErr_Clear();
17589f2f44ceSEd Maste     return StructuredData::StringSP();
17599f2f44ceSEd Maste   }
17609f2f44ceSEd Maste 
17619f2f44ceSEd Maste   if (PyErr_Occurred())
17629f2f44ceSEd Maste     PyErr_Clear();
17639f2f44ceSEd Maste 
17649f2f44ceSEd Maste   // right now we know this function exists and is callable..
1765435933ddSDimitry Andric   PythonObject py_return(
1766435933ddSDimitry Andric       PyRefType::Owned,
1767435933ddSDimitry Andric       PyObject_CallMethod(implementor.get(), callee_name, param_format, tid));
17689f2f44ceSEd Maste 
17699f2f44ceSEd Maste   // if it fails, print the error but otherwise go on
1770435933ddSDimitry Andric   if (PyErr_Occurred()) {
17719f2f44ceSEd Maste     PyErr_Print();
17729f2f44ceSEd Maste     PyErr_Clear();
17739f2f44ceSEd Maste   }
17749f2f44ceSEd Maste 
1775435933ddSDimitry Andric   if (py_return.get()) {
1776444ed5c5SDimitry Andric     PythonBytes result(PyRefType::Borrowed, py_return.get());
1777444ed5c5SDimitry Andric     return result.CreateStructuredString();
17789f2f44ceSEd Maste   }
17794bb0738eSEd Maste   return StructuredData::StringSP();
17804bb0738eSEd Maste }
17819f2f44ceSEd Maste 
OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp,lldb::tid_t tid,lldb::addr_t context)1782435933ddSDimitry Andric StructuredData::DictionarySP ScriptInterpreterPython::OSPlugin_CreateThread(
1783435933ddSDimitry Andric     StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid,
1784435933ddSDimitry Andric     lldb::addr_t context) {
1785435933ddSDimitry Andric   Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
17869f2f44ceSEd Maste 
17879f2f44ceSEd Maste   static char callee_name[] = "create_thread";
17889f2f44ceSEd Maste   std::string param_format;
17899f2f44ceSEd Maste   param_format += GetPythonValueFormatString(tid);
17909f2f44ceSEd Maste   param_format += GetPythonValueFormatString(context);
17919f2f44ceSEd Maste 
17929f2f44ceSEd Maste   if (!os_plugin_object_sp)
17939f2f44ceSEd Maste     return StructuredData::DictionarySP();
17949f2f44ceSEd Maste 
17959f2f44ceSEd Maste   StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
17969f2f44ceSEd Maste   if (!generic)
17979f2f44ceSEd Maste     return nullptr;
17989f2f44ceSEd Maste 
1799435933ddSDimitry Andric   PythonObject implementor(PyRefType::Borrowed,
1800435933ddSDimitry Andric                            (PyObject *)generic->GetValue());
18019f2f44ceSEd Maste 
18029f2f44ceSEd Maste   if (!implementor.IsAllocated())
18039f2f44ceSEd Maste     return StructuredData::DictionarySP();
18049f2f44ceSEd Maste 
1805435933ddSDimitry Andric   PythonObject pmeth(PyRefType::Owned,
1806435933ddSDimitry Andric                      PyObject_GetAttrString(implementor.get(), callee_name));
18079f2f44ceSEd Maste 
18089f2f44ceSEd Maste   if (PyErr_Occurred())
18099f2f44ceSEd Maste     PyErr_Clear();
18109f2f44ceSEd Maste 
18119f2f44ceSEd Maste   if (!pmeth.IsAllocated())
18129f2f44ceSEd Maste     return StructuredData::DictionarySP();
18139f2f44ceSEd Maste 
1814435933ddSDimitry Andric   if (PyCallable_Check(pmeth.get()) == 0) {
18159f2f44ceSEd Maste     if (PyErr_Occurred())
18169f2f44ceSEd Maste       PyErr_Clear();
18179f2f44ceSEd Maste     return StructuredData::DictionarySP();
18189f2f44ceSEd Maste   }
18199f2f44ceSEd Maste 
18209f2f44ceSEd Maste   if (PyErr_Occurred())
18219f2f44ceSEd Maste     PyErr_Clear();
18229f2f44ceSEd Maste 
18239f2f44ceSEd Maste   // right now we know this function exists and is callable..
1824435933ddSDimitry Andric   PythonObject py_return(PyRefType::Owned,
1825435933ddSDimitry Andric                          PyObject_CallMethod(implementor.get(), callee_name,
1826435933ddSDimitry Andric                                              &param_format[0], tid, context));
18279f2f44ceSEd Maste 
18289f2f44ceSEd Maste   // if it fails, print the error but otherwise go on
1829435933ddSDimitry Andric   if (PyErr_Occurred()) {
18309f2f44ceSEd Maste     PyErr_Print();
18319f2f44ceSEd Maste     PyErr_Clear();
18329f2f44ceSEd Maste   }
18339f2f44ceSEd Maste 
1834435933ddSDimitry Andric   if (py_return.get()) {
18359f2f44ceSEd Maste     PythonDictionary result_dict(PyRefType::Borrowed, py_return.get());
18369f2f44ceSEd Maste     return result_dict.CreateStructuredDictionary();
18379f2f44ceSEd Maste   }
18384bb0738eSEd Maste   return StructuredData::DictionarySP();
18394bb0738eSEd Maste }
18409f2f44ceSEd Maste 
CreateScriptedThreadPlan(const char * class_name,lldb::ThreadPlanSP thread_plan_sp)1841435933ddSDimitry Andric StructuredData::ObjectSP ScriptInterpreterPython::CreateScriptedThreadPlan(
1842435933ddSDimitry Andric     const char *class_name, lldb::ThreadPlanSP thread_plan_sp) {
18439f2f44ceSEd Maste   if (class_name == nullptr || class_name[0] == '\0')
18449f2f44ceSEd Maste     return StructuredData::ObjectSP();
18459f2f44ceSEd Maste 
18469f2f44ceSEd Maste   if (!thread_plan_sp.get())
18479f2f44ceSEd Maste     return StructuredData::ObjectSP();
18489f2f44ceSEd Maste 
18499f2f44ceSEd Maste   Debugger &debugger = thread_plan_sp->GetTarget().GetDebugger();
1850435933ddSDimitry Andric   ScriptInterpreter *script_interpreter =
1851435933ddSDimitry Andric       debugger.GetCommandInterpreter().GetScriptInterpreter();
1852435933ddSDimitry Andric   ScriptInterpreterPython *python_interpreter =
1853435933ddSDimitry Andric       static_cast<ScriptInterpreterPython *>(script_interpreter);
18549f2f44ceSEd Maste 
18559f2f44ceSEd Maste   if (!script_interpreter)
18569f2f44ceSEd Maste     return StructuredData::ObjectSP();
18579f2f44ceSEd Maste 
18589f2f44ceSEd Maste   void *ret_val;
18599f2f44ceSEd Maste 
18609f2f44ceSEd Maste   {
1861435933ddSDimitry Andric     Locker py_lock(this,
1862435933ddSDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
18639f2f44ceSEd Maste 
1864435933ddSDimitry Andric     ret_val = g_swig_thread_plan_script(
1865435933ddSDimitry Andric         class_name, python_interpreter->m_dictionary_name.c_str(),
18669f2f44ceSEd Maste         thread_plan_sp);
18679f2f44ceSEd Maste   }
18689f2f44ceSEd Maste 
18699f2f44ceSEd Maste   return StructuredData::ObjectSP(new StructuredPythonObject(ret_val));
18709f2f44ceSEd Maste }
18719f2f44ceSEd Maste 
ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,Event * event,bool & script_error)1872435933ddSDimitry Andric bool ScriptInterpreterPython::ScriptedThreadPlanExplainsStop(
1873435933ddSDimitry Andric     StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) {
18749f2f44ceSEd Maste   bool explains_stop = true;
18759f2f44ceSEd Maste   StructuredData::Generic *generic = nullptr;
18769f2f44ceSEd Maste   if (implementor_sp)
18779f2f44ceSEd Maste     generic = implementor_sp->GetAsGeneric();
1878435933ddSDimitry Andric   if (generic) {
1879435933ddSDimitry Andric     Locker py_lock(this,
1880435933ddSDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1881435933ddSDimitry Andric     explains_stop = g_swig_call_thread_plan(
1882435933ddSDimitry Andric         generic->GetValue(), "explains_stop", event, script_error);
18839f2f44ceSEd Maste     if (script_error)
18849f2f44ceSEd Maste       return true;
18859f2f44ceSEd Maste   }
18869f2f44ceSEd Maste   return explains_stop;
18879f2f44ceSEd Maste }
18889f2f44ceSEd Maste 
ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp,Event * event,bool & script_error)1889435933ddSDimitry Andric bool ScriptInterpreterPython::ScriptedThreadPlanShouldStop(
1890435933ddSDimitry Andric     StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) {
18919f2f44ceSEd Maste   bool should_stop = true;
18929f2f44ceSEd Maste   StructuredData::Generic *generic = nullptr;
18939f2f44ceSEd Maste   if (implementor_sp)
18949f2f44ceSEd Maste     generic = implementor_sp->GetAsGeneric();
1895435933ddSDimitry Andric   if (generic) {
1896435933ddSDimitry Andric     Locker py_lock(this,
1897435933ddSDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1898435933ddSDimitry Andric     should_stop = g_swig_call_thread_plan(generic->GetValue(), "should_stop",
1899435933ddSDimitry Andric                                           event, script_error);
19009f2f44ceSEd Maste     if (script_error)
19019f2f44ceSEd Maste       return true;
19029f2f44ceSEd Maste   }
19039f2f44ceSEd Maste   return should_stop;
19049f2f44ceSEd Maste }
19059f2f44ceSEd Maste 
ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp,bool & script_error)1906435933ddSDimitry Andric bool ScriptInterpreterPython::ScriptedThreadPlanIsStale(
1907435933ddSDimitry Andric     StructuredData::ObjectSP implementor_sp, bool &script_error) {
1908435933ddSDimitry Andric   bool is_stale = true;
1909435933ddSDimitry Andric   StructuredData::Generic *generic = nullptr;
1910435933ddSDimitry Andric   if (implementor_sp)
1911435933ddSDimitry Andric     generic = implementor_sp->GetAsGeneric();
1912435933ddSDimitry Andric   if (generic) {
1913435933ddSDimitry Andric     Locker py_lock(this,
1914435933ddSDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1915435933ddSDimitry Andric     is_stale = g_swig_call_thread_plan(generic->GetValue(), "is_stale", nullptr,
1916435933ddSDimitry Andric                                        script_error);
1917435933ddSDimitry Andric     if (script_error)
1918435933ddSDimitry Andric       return true;
1919435933ddSDimitry Andric   }
1920435933ddSDimitry Andric   return is_stale;
1921435933ddSDimitry Andric }
1922435933ddSDimitry Andric 
ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp,bool & script_error)1923435933ddSDimitry Andric lldb::StateType ScriptInterpreterPython::ScriptedThreadPlanGetRunState(
1924435933ddSDimitry Andric     StructuredData::ObjectSP implementor_sp, bool &script_error) {
19259f2f44ceSEd Maste   bool should_step = false;
19269f2f44ceSEd Maste   StructuredData::Generic *generic = nullptr;
19279f2f44ceSEd Maste   if (implementor_sp)
19289f2f44ceSEd Maste     generic = implementor_sp->GetAsGeneric();
1929435933ddSDimitry Andric   if (generic) {
1930435933ddSDimitry Andric     Locker py_lock(this,
1931435933ddSDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1932435933ddSDimitry Andric     should_step = g_swig_call_thread_plan(generic->GetValue(), "should_step",
1933435933ddSDimitry Andric                                           NULL, script_error);
19349f2f44ceSEd Maste     if (script_error)
19359f2f44ceSEd Maste       should_step = true;
19369f2f44ceSEd Maste   }
19379f2f44ceSEd Maste   if (should_step)
19389f2f44ceSEd Maste     return lldb::eStateStepping;
19399f2f44ceSEd Maste   else
19409f2f44ceSEd Maste     return lldb::eStateRunning;
19419f2f44ceSEd Maste }
19429f2f44ceSEd Maste 
1943*b5893f02SDimitry Andric StructuredData::GenericSP
CreateScriptedBreakpointResolver(const char * class_name,StructuredDataImpl * args_data,lldb::BreakpointSP & bkpt_sp)1944*b5893f02SDimitry Andric ScriptInterpreterPython::CreateScriptedBreakpointResolver(
1945*b5893f02SDimitry Andric     const char *class_name,
1946*b5893f02SDimitry Andric     StructuredDataImpl *args_data,
1947*b5893f02SDimitry Andric     lldb::BreakpointSP &bkpt_sp) {
1948*b5893f02SDimitry Andric 
1949*b5893f02SDimitry Andric   if (class_name == nullptr || class_name[0] == '\0')
1950*b5893f02SDimitry Andric     return StructuredData::GenericSP();
1951*b5893f02SDimitry Andric 
1952*b5893f02SDimitry Andric   if (!bkpt_sp.get())
1953*b5893f02SDimitry Andric     return StructuredData::GenericSP();
1954*b5893f02SDimitry Andric 
1955*b5893f02SDimitry Andric   Debugger &debugger = bkpt_sp->GetTarget().GetDebugger();
1956*b5893f02SDimitry Andric   ScriptInterpreter *script_interpreter =
1957*b5893f02SDimitry Andric       debugger.GetCommandInterpreter().GetScriptInterpreter();
1958*b5893f02SDimitry Andric   ScriptInterpreterPython *python_interpreter =
1959*b5893f02SDimitry Andric       static_cast<ScriptInterpreterPython *>(script_interpreter);
1960*b5893f02SDimitry Andric 
1961*b5893f02SDimitry Andric   if (!script_interpreter)
1962*b5893f02SDimitry Andric     return StructuredData::GenericSP();
1963*b5893f02SDimitry Andric 
1964*b5893f02SDimitry Andric   void *ret_val;
1965*b5893f02SDimitry Andric 
1966*b5893f02SDimitry Andric   {
1967*b5893f02SDimitry Andric     Locker py_lock(this,
1968*b5893f02SDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1969*b5893f02SDimitry Andric 
1970*b5893f02SDimitry Andric     ret_val = g_swig_bkpt_resolver_script(
1971*b5893f02SDimitry Andric         class_name, python_interpreter->m_dictionary_name.c_str(),
1972*b5893f02SDimitry Andric         args_data, bkpt_sp);
1973*b5893f02SDimitry Andric   }
1974*b5893f02SDimitry Andric 
1975*b5893f02SDimitry Andric   return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
1976*b5893f02SDimitry Andric }
1977*b5893f02SDimitry Andric 
1978*b5893f02SDimitry Andric bool
ScriptedBreakpointResolverSearchCallback(StructuredData::GenericSP implementor_sp,SymbolContext * sym_ctx)1979*b5893f02SDimitry Andric ScriptInterpreterPython::ScriptedBreakpointResolverSearchCallback(
1980*b5893f02SDimitry Andric     StructuredData::GenericSP implementor_sp,
1981*b5893f02SDimitry Andric     SymbolContext *sym_ctx) {
1982*b5893f02SDimitry Andric   bool should_continue = false;
1983*b5893f02SDimitry Andric 
1984*b5893f02SDimitry Andric   if (implementor_sp) {
1985*b5893f02SDimitry Andric     Locker py_lock(this,
1986*b5893f02SDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1987*b5893f02SDimitry Andric     should_continue
1988*b5893f02SDimitry Andric         = g_swig_call_bkpt_resolver(implementor_sp->GetValue(), "__callback__",
1989*b5893f02SDimitry Andric                                     sym_ctx);
1990*b5893f02SDimitry Andric     if (PyErr_Occurred()) {
1991*b5893f02SDimitry Andric       PyErr_Print();
1992*b5893f02SDimitry Andric       PyErr_Clear();
1993*b5893f02SDimitry Andric     }
1994*b5893f02SDimitry Andric   }
1995*b5893f02SDimitry Andric   return should_continue;
1996*b5893f02SDimitry Andric }
1997*b5893f02SDimitry Andric 
1998*b5893f02SDimitry Andric lldb::SearchDepth
ScriptedBreakpointResolverSearchDepth(StructuredData::GenericSP implementor_sp)1999*b5893f02SDimitry Andric ScriptInterpreterPython::ScriptedBreakpointResolverSearchDepth(
2000*b5893f02SDimitry Andric     StructuredData::GenericSP implementor_sp) {
2001*b5893f02SDimitry Andric   int depth_as_int = lldb::eSearchDepthModule;
2002*b5893f02SDimitry Andric   if (implementor_sp) {
2003*b5893f02SDimitry Andric     Locker py_lock(this,
2004*b5893f02SDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2005*b5893f02SDimitry Andric     depth_as_int
2006*b5893f02SDimitry Andric         = g_swig_call_bkpt_resolver(implementor_sp->GetValue(), "__get_depth__", nullptr);
2007*b5893f02SDimitry Andric     if (PyErr_Occurred()) {
2008*b5893f02SDimitry Andric       PyErr_Print();
2009*b5893f02SDimitry Andric       PyErr_Clear();
2010*b5893f02SDimitry Andric     }
2011*b5893f02SDimitry Andric   }
2012*b5893f02SDimitry Andric   if (depth_as_int == lldb::eSearchDepthInvalid)
2013*b5893f02SDimitry Andric     return lldb::eSearchDepthModule;
2014*b5893f02SDimitry Andric 
2015*b5893f02SDimitry Andric   if (depth_as_int <= lldb::kLastSearchDepthKind)
2016*b5893f02SDimitry Andric     return (lldb::SearchDepth) depth_as_int;
2017*b5893f02SDimitry Andric   else
2018*b5893f02SDimitry Andric     return lldb::eSearchDepthModule;
2019*b5893f02SDimitry Andric }
2020*b5893f02SDimitry Andric 
20219f2f44ceSEd Maste StructuredData::ObjectSP
LoadPluginModule(const FileSpec & file_spec,lldb_private::Status & error)2022435933ddSDimitry Andric ScriptInterpreterPython::LoadPluginModule(const FileSpec &file_spec,
20235517e702SDimitry Andric                                           lldb_private::Status &error) {
2024*b5893f02SDimitry Andric   if (!FileSystem::Instance().Exists(file_spec)) {
20259f2f44ceSEd Maste     error.SetErrorString("no such file");
20269f2f44ceSEd Maste     return StructuredData::ObjectSP();
20279f2f44ceSEd Maste   }
20289f2f44ceSEd Maste 
20299f2f44ceSEd Maste   StructuredData::ObjectSP module_sp;
20309f2f44ceSEd Maste 
2031435933ddSDimitry Andric   if (LoadScriptingModule(file_spec.GetPath().c_str(), true, true, error,
2032435933ddSDimitry Andric                           &module_sp))
20339f2f44ceSEd Maste     return module_sp;
20349f2f44ceSEd Maste 
20359f2f44ceSEd Maste   return StructuredData::ObjectSP();
20369f2f44ceSEd Maste }
20379f2f44ceSEd Maste 
GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp,Target * target,const char * setting_name,lldb_private::Status & error)2038435933ddSDimitry Andric StructuredData::DictionarySP ScriptInterpreterPython::GetDynamicSettings(
2039435933ddSDimitry Andric     StructuredData::ObjectSP plugin_module_sp, Target *target,
20405517e702SDimitry Andric     const char *setting_name, lldb_private::Status &error) {
2041435933ddSDimitry Andric   if (!plugin_module_sp || !target || !setting_name || !setting_name[0] ||
2042435933ddSDimitry Andric       !g_swig_plugin_get)
20439f2f44ceSEd Maste     return StructuredData::DictionarySP();
20449f2f44ceSEd Maste   StructuredData::Generic *generic = plugin_module_sp->GetAsGeneric();
20459f2f44ceSEd Maste   if (!generic)
20469f2f44ceSEd Maste     return StructuredData::DictionarySP();
20479f2f44ceSEd Maste 
20489f2f44ceSEd Maste   PythonObject reply_pyobj;
2049435933ddSDimitry Andric   Locker py_lock(this,
2050435933ddSDimitry Andric                  Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
20519f2f44ceSEd Maste   TargetSP target_sp(target->shared_from_this());
20529f2f44ceSEd Maste   reply_pyobj.Reset(PyRefType::Owned,
2053435933ddSDimitry Andric                     (PyObject *)g_swig_plugin_get(generic->GetValue(),
2054435933ddSDimitry Andric                                                   setting_name, target_sp));
20559f2f44ceSEd Maste 
20569f2f44ceSEd Maste   PythonDictionary py_dict(PyRefType::Borrowed, reply_pyobj.get());
20579f2f44ceSEd Maste   return py_dict.CreateStructuredDictionary();
20589f2f44ceSEd Maste }
20599f2f44ceSEd Maste 
20609f2f44ceSEd Maste StructuredData::ObjectSP
CreateSyntheticScriptedProvider(const char * class_name,lldb::ValueObjectSP valobj)2061435933ddSDimitry Andric ScriptInterpreterPython::CreateSyntheticScriptedProvider(
2062435933ddSDimitry Andric     const char *class_name, lldb::ValueObjectSP valobj) {
20639f2f44ceSEd Maste   if (class_name == nullptr || class_name[0] == '\0')
20649f2f44ceSEd Maste     return StructuredData::ObjectSP();
20659f2f44ceSEd Maste 
20669f2f44ceSEd Maste   if (!valobj.get())
20679f2f44ceSEd Maste     return StructuredData::ObjectSP();
20689f2f44ceSEd Maste 
20699f2f44ceSEd Maste   ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
20709f2f44ceSEd Maste   Target *target = exe_ctx.GetTargetPtr();
20719f2f44ceSEd Maste 
20729f2f44ceSEd Maste   if (!target)
20739f2f44ceSEd Maste     return StructuredData::ObjectSP();
20749f2f44ceSEd Maste 
20759f2f44ceSEd Maste   Debugger &debugger = target->GetDebugger();
2076435933ddSDimitry Andric   ScriptInterpreter *script_interpreter =
2077435933ddSDimitry Andric       debugger.GetCommandInterpreter().GetScriptInterpreter();
2078435933ddSDimitry Andric   ScriptInterpreterPython *python_interpreter =
2079435933ddSDimitry Andric       (ScriptInterpreterPython *)script_interpreter;
20809f2f44ceSEd Maste 
20819f2f44ceSEd Maste   if (!script_interpreter)
20829f2f44ceSEd Maste     return StructuredData::ObjectSP();
20839f2f44ceSEd Maste 
20849f2f44ceSEd Maste   void *ret_val = nullptr;
20859f2f44ceSEd Maste 
20869f2f44ceSEd Maste   {
2087435933ddSDimitry Andric     Locker py_lock(this,
2088435933ddSDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2089435933ddSDimitry Andric     ret_val = g_swig_synthetic_script(
2090435933ddSDimitry Andric         class_name, python_interpreter->m_dictionary_name.c_str(), valobj);
20919f2f44ceSEd Maste   }
20929f2f44ceSEd Maste 
20939f2f44ceSEd Maste   return StructuredData::ObjectSP(new StructuredPythonObject(ret_val));
20949f2f44ceSEd Maste }
20959f2f44ceSEd Maste 
20969f2f44ceSEd Maste StructuredData::GenericSP
CreateScriptCommandObject(const char * class_name)2097435933ddSDimitry Andric ScriptInterpreterPython::CreateScriptCommandObject(const char *class_name) {
2098435933ddSDimitry Andric   DebuggerSP debugger_sp(
2099435933ddSDimitry Andric       GetCommandInterpreter().GetDebugger().shared_from_this());
21009f2f44ceSEd Maste 
21019f2f44ceSEd Maste   if (class_name == nullptr || class_name[0] == '\0')
21029f2f44ceSEd Maste     return StructuredData::GenericSP();
21039f2f44ceSEd Maste 
21049f2f44ceSEd Maste   if (!debugger_sp.get())
21059f2f44ceSEd Maste     return StructuredData::GenericSP();
21069f2f44ceSEd Maste 
21079f2f44ceSEd Maste   void *ret_val;
21089f2f44ceSEd Maste 
21099f2f44ceSEd Maste   {
2110435933ddSDimitry Andric     Locker py_lock(this,
2111435933ddSDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2112435933ddSDimitry Andric     ret_val =
2113435933ddSDimitry Andric         g_swig_create_cmd(class_name, m_dictionary_name.c_str(), debugger_sp);
21149f2f44ceSEd Maste   }
21159f2f44ceSEd Maste 
21169f2f44ceSEd Maste   return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
21179f2f44ceSEd Maste }
21189f2f44ceSEd Maste 
GenerateTypeScriptFunction(const char * oneliner,std::string & output,const void * name_token)2119435933ddSDimitry Andric bool ScriptInterpreterPython::GenerateTypeScriptFunction(
2120435933ddSDimitry Andric     const char *oneliner, std::string &output, const void *name_token) {
21219f2f44ceSEd Maste   StringList input;
21229f2f44ceSEd Maste   input.SplitIntoLines(oneliner, strlen(oneliner));
21239f2f44ceSEd Maste   return GenerateTypeScriptFunction(input, output, name_token);
21249f2f44ceSEd Maste }
21259f2f44ceSEd Maste 
GenerateTypeSynthClass(const char * oneliner,std::string & output,const void * name_token)2126435933ddSDimitry Andric bool ScriptInterpreterPython::GenerateTypeSynthClass(const char *oneliner,
2127435933ddSDimitry Andric                                                      std::string &output,
2128435933ddSDimitry Andric                                                      const void *name_token) {
21299f2f44ceSEd Maste   StringList input;
21309f2f44ceSEd Maste   input.SplitIntoLines(oneliner, strlen(oneliner));
21319f2f44ceSEd Maste   return GenerateTypeSynthClass(input, output, name_token);
21329f2f44ceSEd Maste }
21339f2f44ceSEd Maste 
GenerateBreakpointCommandCallbackData(StringList & user_input,std::string & output)21345517e702SDimitry Andric Status ScriptInterpreterPython::GenerateBreakpointCommandCallbackData(
2135435933ddSDimitry Andric     StringList &user_input, std::string &output) {
21369f2f44ceSEd Maste   static uint32_t num_created_functions = 0;
21379f2f44ceSEd Maste   user_input.RemoveBlankLines();
21389f2f44ceSEd Maste   StreamString sstr;
21395517e702SDimitry Andric   Status error;
2140435933ddSDimitry Andric   if (user_input.GetSize() == 0) {
21419f2f44ceSEd Maste     error.SetErrorString("No input data.");
21429f2f44ceSEd Maste     return error;
21439f2f44ceSEd Maste   }
21449f2f44ceSEd Maste 
2145435933ddSDimitry Andric   std::string auto_generated_function_name(GenerateUniqueName(
2146435933ddSDimitry Andric       "lldb_autogen_python_bp_callback_func_", num_created_functions));
2147435933ddSDimitry Andric   sstr.Printf("def %s (frame, bp_loc, internal_dict):",
2148435933ddSDimitry Andric               auto_generated_function_name.c_str());
21499f2f44ceSEd Maste 
21509f2f44ceSEd Maste   error = GenerateFunction(sstr.GetData(), user_input);
21519f2f44ceSEd Maste   if (!error.Success())
21529f2f44ceSEd Maste     return error;
21539f2f44ceSEd Maste 
21549f2f44ceSEd Maste   // Store the name of the auto-generated function to be called.
21559f2f44ceSEd Maste   output.assign(auto_generated_function_name);
21569f2f44ceSEd Maste   return error;
21579f2f44ceSEd Maste }
21589f2f44ceSEd Maste 
GenerateWatchpointCommandCallbackData(StringList & user_input,std::string & output)2159435933ddSDimitry Andric bool ScriptInterpreterPython::GenerateWatchpointCommandCallbackData(
2160435933ddSDimitry Andric     StringList &user_input, std::string &output) {
21619f2f44ceSEd Maste   static uint32_t num_created_functions = 0;
21629f2f44ceSEd Maste   user_input.RemoveBlankLines();
21639f2f44ceSEd Maste   StreamString sstr;
21649f2f44ceSEd Maste 
21659f2f44ceSEd Maste   if (user_input.GetSize() == 0)
21669f2f44ceSEd Maste     return false;
21679f2f44ceSEd Maste 
2168435933ddSDimitry Andric   std::string auto_generated_function_name(GenerateUniqueName(
2169435933ddSDimitry Andric       "lldb_autogen_python_wp_callback_func_", num_created_functions));
2170435933ddSDimitry Andric   sstr.Printf("def %s (frame, wp, internal_dict):",
2171435933ddSDimitry Andric               auto_generated_function_name.c_str());
21729f2f44ceSEd Maste 
21739f2f44ceSEd Maste   if (!GenerateFunction(sstr.GetData(), user_input).Success())
21749f2f44ceSEd Maste     return false;
21759f2f44ceSEd Maste 
21769f2f44ceSEd Maste   // Store the name of the auto-generated function to be called.
21779f2f44ceSEd Maste   output.assign(auto_generated_function_name);
21789f2f44ceSEd Maste   return true;
21799f2f44ceSEd Maste }
21809f2f44ceSEd Maste 
GetScriptedSummary(const char * python_function_name,lldb::ValueObjectSP valobj,StructuredData::ObjectSP & callee_wrapper_sp,const TypeSummaryOptions & options,std::string & retval)2181435933ddSDimitry Andric bool ScriptInterpreterPython::GetScriptedSummary(
2182435933ddSDimitry Andric     const char *python_function_name, lldb::ValueObjectSP valobj,
2183435933ddSDimitry Andric     StructuredData::ObjectSP &callee_wrapper_sp,
2184435933ddSDimitry Andric     const TypeSummaryOptions &options, std::string &retval) {
21859f2f44ceSEd Maste 
21865517e702SDimitry Andric   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
21875517e702SDimitry Andric   Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
21889f2f44ceSEd Maste 
2189435933ddSDimitry Andric   if (!valobj.get()) {
21909f2f44ceSEd Maste     retval.assign("<no object>");
21919f2f44ceSEd Maste     return false;
21929f2f44ceSEd Maste   }
21939f2f44ceSEd Maste 
21949f2f44ceSEd Maste   void *old_callee = nullptr;
21959f2f44ceSEd Maste   StructuredData::Generic *generic = nullptr;
2196435933ddSDimitry Andric   if (callee_wrapper_sp) {
21979f2f44ceSEd Maste     generic = callee_wrapper_sp->GetAsGeneric();
21989f2f44ceSEd Maste     if (generic)
21999f2f44ceSEd Maste       old_callee = generic->GetValue();
22009f2f44ceSEd Maste   }
22019f2f44ceSEd Maste   void *new_callee = old_callee;
22029f2f44ceSEd Maste 
22039f2f44ceSEd Maste   bool ret_val;
2204435933ddSDimitry Andric   if (python_function_name && *python_function_name) {
22059f2f44ceSEd Maste     {
2206435933ddSDimitry Andric       Locker py_lock(this, Locker::AcquireLock | Locker::InitSession |
2207435933ddSDimitry Andric                                Locker::NoSTDIN);
22089f2f44ceSEd Maste       {
22099f2f44ceSEd Maste         TypeSummaryOptionsSP options_sp(new TypeSummaryOptions(options));
22109f2f44ceSEd Maste 
22115517e702SDimitry Andric         static Timer::Category func_cat("g_swig_typescript_callback");
22125517e702SDimitry Andric         Timer scoped_timer(func_cat, "g_swig_typescript_callback");
2213435933ddSDimitry Andric         ret_val = g_swig_typescript_callback(
2214435933ddSDimitry Andric             python_function_name, GetSessionDictionary().get(), valobj,
2215435933ddSDimitry Andric             &new_callee, options_sp, retval);
22169f2f44ceSEd Maste       }
22179f2f44ceSEd Maste     }
2218435933ddSDimitry Andric   } else {
22199f2f44ceSEd Maste     retval.assign("<no function name>");
22209f2f44ceSEd Maste     return false;
22219f2f44ceSEd Maste   }
22229f2f44ceSEd Maste 
22239f2f44ceSEd Maste   if (new_callee && old_callee != new_callee)
22249f2f44ceSEd Maste     callee_wrapper_sp.reset(new StructuredPythonObject(new_callee));
22259f2f44ceSEd Maste 
22269f2f44ceSEd Maste   return ret_val;
22279f2f44ceSEd Maste }
22289f2f44ceSEd Maste 
Clear()2229435933ddSDimitry Andric void ScriptInterpreterPython::Clear() {
22309f2f44ceSEd Maste   // Release any global variables that might have strong references to
22319f2f44ceSEd Maste   // LLDB objects when clearing the python script interpreter.
2232435933ddSDimitry Andric   Locker locker(this, ScriptInterpreterPython::Locker::AcquireLock,
22339f2f44ceSEd Maste                 ScriptInterpreterPython::Locker::FreeAcquiredLock);
22349f2f44ceSEd Maste 
2235435933ddSDimitry Andric   // This may be called as part of Py_Finalize.  In that case the modules are
22364ba319b5SDimitry Andric   // destroyed in random order and we can't guarantee that we can access these.
22379f2f44ceSEd Maste   if (Py_IsInitialized())
2238435933ddSDimitry Andric     PyRun_SimpleString("lldb.debugger = None; lldb.target = None; lldb.process "
2239435933ddSDimitry Andric                        "= None; lldb.thread = None; lldb.frame = None");
22409f2f44ceSEd Maste }
22419f2f44ceSEd Maste 
BreakpointCallbackFunction(void * baton,StoppointCallbackContext * context,user_id_t break_id,user_id_t break_loc_id)2242435933ddSDimitry Andric bool ScriptInterpreterPython::BreakpointCallbackFunction(
2243435933ddSDimitry Andric     void *baton, StoppointCallbackContext *context, user_id_t break_id,
2244435933ddSDimitry Andric     user_id_t break_loc_id) {
2245435933ddSDimitry Andric   CommandDataPython *bp_option_data = (CommandDataPython *)baton;
22469f2f44ceSEd Maste   const char *python_function_name = bp_option_data->script_source.c_str();
22479f2f44ceSEd Maste 
22489f2f44ceSEd Maste   if (!context)
22499f2f44ceSEd Maste     return true;
22509f2f44ceSEd Maste 
22519f2f44ceSEd Maste   ExecutionContext exe_ctx(context->exe_ctx_ref);
22529f2f44ceSEd Maste   Target *target = exe_ctx.GetTargetPtr();
22539f2f44ceSEd Maste 
22549f2f44ceSEd Maste   if (!target)
22559f2f44ceSEd Maste     return true;
22569f2f44ceSEd Maste 
22579f2f44ceSEd Maste   Debugger &debugger = target->GetDebugger();
2258435933ddSDimitry Andric   ScriptInterpreter *script_interpreter =
2259435933ddSDimitry Andric       debugger.GetCommandInterpreter().GetScriptInterpreter();
2260435933ddSDimitry Andric   ScriptInterpreterPython *python_interpreter =
2261435933ddSDimitry Andric       (ScriptInterpreterPython *)script_interpreter;
22629f2f44ceSEd Maste 
22639f2f44ceSEd Maste   if (!script_interpreter)
22649f2f44ceSEd Maste     return true;
22659f2f44ceSEd Maste 
2266435933ddSDimitry Andric   if (python_function_name && python_function_name[0]) {
22679f2f44ceSEd Maste     const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
22689f2f44ceSEd Maste     BreakpointSP breakpoint_sp = target->GetBreakpointByID(break_id);
2269435933ddSDimitry Andric     if (breakpoint_sp) {
2270435933ddSDimitry Andric       const BreakpointLocationSP bp_loc_sp(
2271435933ddSDimitry Andric           breakpoint_sp->FindLocationByID(break_loc_id));
22729f2f44ceSEd Maste 
2273435933ddSDimitry Andric       if (stop_frame_sp && bp_loc_sp) {
22749f2f44ceSEd Maste         bool ret_val = true;
22759f2f44ceSEd Maste         {
2276435933ddSDimitry Andric           Locker py_lock(python_interpreter, Locker::AcquireLock |
2277435933ddSDimitry Andric                                                  Locker::InitSession |
2278435933ddSDimitry Andric                                                  Locker::NoSTDIN);
2279435933ddSDimitry Andric           ret_val = g_swig_breakpoint_callback(
2280435933ddSDimitry Andric               python_function_name,
2281435933ddSDimitry Andric               python_interpreter->m_dictionary_name.c_str(), stop_frame_sp,
22829f2f44ceSEd Maste               bp_loc_sp);
22839f2f44ceSEd Maste         }
22849f2f44ceSEd Maste         return ret_val;
22859f2f44ceSEd Maste       }
22869f2f44ceSEd Maste     }
22879f2f44ceSEd Maste   }
22889f2f44ceSEd Maste   // We currently always true so we stop in case anything goes wrong when
22899f2f44ceSEd Maste   // trying to call the script function
22909f2f44ceSEd Maste   return true;
22919f2f44ceSEd Maste }
22929f2f44ceSEd Maste 
WatchpointCallbackFunction(void * baton,StoppointCallbackContext * context,user_id_t watch_id)2293435933ddSDimitry Andric bool ScriptInterpreterPython::WatchpointCallbackFunction(
2294435933ddSDimitry Andric     void *baton, StoppointCallbackContext *context, user_id_t watch_id) {
2295435933ddSDimitry Andric   WatchpointOptions::CommandData *wp_option_data =
2296435933ddSDimitry Andric       (WatchpointOptions::CommandData *)baton;
22979f2f44ceSEd Maste   const char *python_function_name = wp_option_data->script_source.c_str();
22989f2f44ceSEd Maste 
22999f2f44ceSEd Maste   if (!context)
23009f2f44ceSEd Maste     return true;
23019f2f44ceSEd Maste 
23029f2f44ceSEd Maste   ExecutionContext exe_ctx(context->exe_ctx_ref);
23039f2f44ceSEd Maste   Target *target = exe_ctx.GetTargetPtr();
23049f2f44ceSEd Maste 
23059f2f44ceSEd Maste   if (!target)
23069f2f44ceSEd Maste     return true;
23079f2f44ceSEd Maste 
23089f2f44ceSEd Maste   Debugger &debugger = target->GetDebugger();
2309435933ddSDimitry Andric   ScriptInterpreter *script_interpreter =
2310435933ddSDimitry Andric       debugger.GetCommandInterpreter().GetScriptInterpreter();
2311435933ddSDimitry Andric   ScriptInterpreterPython *python_interpreter =
2312435933ddSDimitry Andric       (ScriptInterpreterPython *)script_interpreter;
23139f2f44ceSEd Maste 
23149f2f44ceSEd Maste   if (!script_interpreter)
23159f2f44ceSEd Maste     return true;
23169f2f44ceSEd Maste 
2317435933ddSDimitry Andric   if (python_function_name && python_function_name[0]) {
23189f2f44ceSEd Maste     const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
23199f2f44ceSEd Maste     WatchpointSP wp_sp = target->GetWatchpointList().FindByID(watch_id);
2320435933ddSDimitry Andric     if (wp_sp) {
2321435933ddSDimitry Andric       if (stop_frame_sp && wp_sp) {
23229f2f44ceSEd Maste         bool ret_val = true;
23239f2f44ceSEd Maste         {
2324435933ddSDimitry Andric           Locker py_lock(python_interpreter, Locker::AcquireLock |
2325435933ddSDimitry Andric                                                  Locker::InitSession |
2326435933ddSDimitry Andric                                                  Locker::NoSTDIN);
2327435933ddSDimitry Andric           ret_val = g_swig_watchpoint_callback(
2328435933ddSDimitry Andric               python_function_name,
2329435933ddSDimitry Andric               python_interpreter->m_dictionary_name.c_str(), stop_frame_sp,
23309f2f44ceSEd Maste               wp_sp);
23319f2f44ceSEd Maste         }
23329f2f44ceSEd Maste         return ret_val;
23339f2f44ceSEd Maste       }
23349f2f44ceSEd Maste     }
23359f2f44ceSEd Maste   }
23369f2f44ceSEd Maste   // We currently always true so we stop in case anything goes wrong when
23379f2f44ceSEd Maste   // trying to call the script function
23389f2f44ceSEd Maste   return true;
23399f2f44ceSEd Maste }
23409f2f44ceSEd Maste 
CalculateNumChildren(const StructuredData::ObjectSP & implementor_sp,uint32_t max)2341435933ddSDimitry Andric size_t ScriptInterpreterPython::CalculateNumChildren(
2342435933ddSDimitry Andric     const StructuredData::ObjectSP &implementor_sp, uint32_t max) {
23439f2f44ceSEd Maste   if (!implementor_sp)
23449f2f44ceSEd Maste     return 0;
23459f2f44ceSEd Maste   StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
23469f2f44ceSEd Maste   if (!generic)
23479f2f44ceSEd Maste     return 0;
23489f2f44ceSEd Maste   void *implementor = generic->GetValue();
23499f2f44ceSEd Maste   if (!implementor)
23509f2f44ceSEd Maste     return 0;
23519f2f44ceSEd Maste 
23529f2f44ceSEd Maste   if (!g_swig_calc_children)
23539f2f44ceSEd Maste     return 0;
23549f2f44ceSEd Maste 
23559f2f44ceSEd Maste   size_t ret_val = 0;
23569f2f44ceSEd Maste 
23579f2f44ceSEd Maste   {
2358435933ddSDimitry Andric     Locker py_lock(this,
2359435933ddSDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
23609f2f44ceSEd Maste     ret_val = g_swig_calc_children(implementor, max);
23619f2f44ceSEd Maste   }
23629f2f44ceSEd Maste 
23639f2f44ceSEd Maste   return ret_val;
23649f2f44ceSEd Maste }
23659f2f44ceSEd Maste 
GetChildAtIndex(const StructuredData::ObjectSP & implementor_sp,uint32_t idx)2366435933ddSDimitry Andric lldb::ValueObjectSP ScriptInterpreterPython::GetChildAtIndex(
2367435933ddSDimitry Andric     const StructuredData::ObjectSP &implementor_sp, uint32_t idx) {
23689f2f44ceSEd Maste   if (!implementor_sp)
23699f2f44ceSEd Maste     return lldb::ValueObjectSP();
23709f2f44ceSEd Maste 
23719f2f44ceSEd Maste   StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
23729f2f44ceSEd Maste   if (!generic)
23739f2f44ceSEd Maste     return lldb::ValueObjectSP();
23749f2f44ceSEd Maste   void *implementor = generic->GetValue();
23759f2f44ceSEd Maste   if (!implementor)
23769f2f44ceSEd Maste     return lldb::ValueObjectSP();
23779f2f44ceSEd Maste 
23789f2f44ceSEd Maste   if (!g_swig_get_child_index || !g_swig_cast_to_sbvalue)
23799f2f44ceSEd Maste     return lldb::ValueObjectSP();
23809f2f44ceSEd Maste 
23819f2f44ceSEd Maste   lldb::ValueObjectSP ret_val;
23829f2f44ceSEd Maste 
23839f2f44ceSEd Maste   {
2384435933ddSDimitry Andric     Locker py_lock(this,
2385435933ddSDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
23869f2f44ceSEd Maste     void *child_ptr = g_swig_get_child_index(implementor, idx);
2387435933ddSDimitry Andric     if (child_ptr != nullptr && child_ptr != Py_None) {
2388435933ddSDimitry Andric       lldb::SBValue *sb_value_ptr =
2389435933ddSDimitry Andric           (lldb::SBValue *)g_swig_cast_to_sbvalue(child_ptr);
23909f2f44ceSEd Maste       if (sb_value_ptr == nullptr)
23919f2f44ceSEd Maste         Py_XDECREF(child_ptr);
23929f2f44ceSEd Maste       else
23939f2f44ceSEd Maste         ret_val = g_swig_get_valobj_sp_from_sbvalue(sb_value_ptr);
2394435933ddSDimitry Andric     } else {
23959f2f44ceSEd Maste       Py_XDECREF(child_ptr);
23969f2f44ceSEd Maste     }
23979f2f44ceSEd Maste   }
23989f2f44ceSEd Maste 
23999f2f44ceSEd Maste   return ret_val;
24009f2f44ceSEd Maste }
24019f2f44ceSEd Maste 
GetIndexOfChildWithName(const StructuredData::ObjectSP & implementor_sp,const char * child_name)2402435933ddSDimitry Andric int ScriptInterpreterPython::GetIndexOfChildWithName(
2403435933ddSDimitry Andric     const StructuredData::ObjectSP &implementor_sp, const char *child_name) {
24049f2f44ceSEd Maste   if (!implementor_sp)
24059f2f44ceSEd Maste     return UINT32_MAX;
24069f2f44ceSEd Maste 
24079f2f44ceSEd Maste   StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
24089f2f44ceSEd Maste   if (!generic)
24099f2f44ceSEd Maste     return UINT32_MAX;
24109f2f44ceSEd Maste   void *implementor = generic->GetValue();
24119f2f44ceSEd Maste   if (!implementor)
24129f2f44ceSEd Maste     return UINT32_MAX;
24139f2f44ceSEd Maste 
24149f2f44ceSEd Maste   if (!g_swig_get_index_child)
24159f2f44ceSEd Maste     return UINT32_MAX;
24169f2f44ceSEd Maste 
24179f2f44ceSEd Maste   int ret_val = UINT32_MAX;
24189f2f44ceSEd Maste 
24199f2f44ceSEd Maste   {
2420435933ddSDimitry Andric     Locker py_lock(this,
2421435933ddSDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
24229f2f44ceSEd Maste     ret_val = g_swig_get_index_child(implementor, child_name);
24239f2f44ceSEd Maste   }
24249f2f44ceSEd Maste 
24259f2f44ceSEd Maste   return ret_val;
24269f2f44ceSEd Maste }
24279f2f44ceSEd Maste 
UpdateSynthProviderInstance(const StructuredData::ObjectSP & implementor_sp)2428435933ddSDimitry Andric bool ScriptInterpreterPython::UpdateSynthProviderInstance(
2429435933ddSDimitry Andric     const StructuredData::ObjectSP &implementor_sp) {
24309f2f44ceSEd Maste   bool ret_val = false;
24319f2f44ceSEd Maste 
24329f2f44ceSEd Maste   if (!implementor_sp)
24339f2f44ceSEd Maste     return ret_val;
24349f2f44ceSEd Maste 
24359f2f44ceSEd Maste   StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
24369f2f44ceSEd Maste   if (!generic)
24379f2f44ceSEd Maste     return ret_val;
24389f2f44ceSEd Maste   void *implementor = generic->GetValue();
24399f2f44ceSEd Maste   if (!implementor)
24409f2f44ceSEd Maste     return ret_val;
24419f2f44ceSEd Maste 
24429f2f44ceSEd Maste   if (!g_swig_update_provider)
24439f2f44ceSEd Maste     return ret_val;
24449f2f44ceSEd Maste 
24459f2f44ceSEd Maste   {
2446435933ddSDimitry Andric     Locker py_lock(this,
2447435933ddSDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
24489f2f44ceSEd Maste     ret_val = g_swig_update_provider(implementor);
24499f2f44ceSEd Maste   }
24509f2f44ceSEd Maste 
24519f2f44ceSEd Maste   return ret_val;
24529f2f44ceSEd Maste }
24539f2f44ceSEd Maste 
MightHaveChildrenSynthProviderInstance(const StructuredData::ObjectSP & implementor_sp)2454435933ddSDimitry Andric bool ScriptInterpreterPython::MightHaveChildrenSynthProviderInstance(
2455435933ddSDimitry Andric     const StructuredData::ObjectSP &implementor_sp) {
24569f2f44ceSEd Maste   bool ret_val = false;
24579f2f44ceSEd Maste 
24589f2f44ceSEd Maste   if (!implementor_sp)
24599f2f44ceSEd Maste     return ret_val;
24609f2f44ceSEd Maste 
24619f2f44ceSEd Maste   StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
24629f2f44ceSEd Maste   if (!generic)
24639f2f44ceSEd Maste     return ret_val;
24649f2f44ceSEd Maste   void *implementor = generic->GetValue();
24659f2f44ceSEd Maste   if (!implementor)
24669f2f44ceSEd Maste     return ret_val;
24679f2f44ceSEd Maste 
24689f2f44ceSEd Maste   if (!g_swig_mighthavechildren_provider)
24699f2f44ceSEd Maste     return ret_val;
24709f2f44ceSEd Maste 
24719f2f44ceSEd Maste   {
2472435933ddSDimitry Andric     Locker py_lock(this,
2473435933ddSDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
24749f2f44ceSEd Maste     ret_val = g_swig_mighthavechildren_provider(implementor);
24759f2f44ceSEd Maste   }
24769f2f44ceSEd Maste 
24779f2f44ceSEd Maste   return ret_val;
24789f2f44ceSEd Maste }
24799f2f44ceSEd Maste 
GetSyntheticValue(const StructuredData::ObjectSP & implementor_sp)2480435933ddSDimitry Andric lldb::ValueObjectSP ScriptInterpreterPython::GetSyntheticValue(
2481435933ddSDimitry Andric     const StructuredData::ObjectSP &implementor_sp) {
24829f2f44ceSEd Maste   lldb::ValueObjectSP ret_val(nullptr);
24839f2f44ceSEd Maste 
24849f2f44ceSEd Maste   if (!implementor_sp)
24859f2f44ceSEd Maste     return ret_val;
24869f2f44ceSEd Maste 
24879f2f44ceSEd Maste   StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
24889f2f44ceSEd Maste   if (!generic)
24899f2f44ceSEd Maste     return ret_val;
24909f2f44ceSEd Maste   void *implementor = generic->GetValue();
24919f2f44ceSEd Maste   if (!implementor)
24929f2f44ceSEd Maste     return ret_val;
24939f2f44ceSEd Maste 
2494435933ddSDimitry Andric   if (!g_swig_getvalue_provider || !g_swig_cast_to_sbvalue ||
2495435933ddSDimitry Andric       !g_swig_get_valobj_sp_from_sbvalue)
24969f2f44ceSEd Maste     return ret_val;
24979f2f44ceSEd Maste 
24989f2f44ceSEd Maste   {
2499435933ddSDimitry Andric     Locker py_lock(this,
2500435933ddSDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
25019f2f44ceSEd Maste     void *child_ptr = g_swig_getvalue_provider(implementor);
2502435933ddSDimitry Andric     if (child_ptr != nullptr && child_ptr != Py_None) {
2503435933ddSDimitry Andric       lldb::SBValue *sb_value_ptr =
2504435933ddSDimitry Andric           (lldb::SBValue *)g_swig_cast_to_sbvalue(child_ptr);
25059f2f44ceSEd Maste       if (sb_value_ptr == nullptr)
25069f2f44ceSEd Maste         Py_XDECREF(child_ptr);
25079f2f44ceSEd Maste       else
25089f2f44ceSEd Maste         ret_val = g_swig_get_valobj_sp_from_sbvalue(sb_value_ptr);
2509435933ddSDimitry Andric     } else {
25109f2f44ceSEd Maste       Py_XDECREF(child_ptr);
25119f2f44ceSEd Maste     }
25129f2f44ceSEd Maste   }
25139f2f44ceSEd Maste 
25149f2f44ceSEd Maste   return ret_val;
25159f2f44ceSEd Maste }
25169f2f44ceSEd Maste 
GetSyntheticTypeName(const StructuredData::ObjectSP & implementor_sp)2517435933ddSDimitry Andric ConstString ScriptInterpreterPython::GetSyntheticTypeName(
2518435933ddSDimitry Andric     const StructuredData::ObjectSP &implementor_sp) {
2519435933ddSDimitry Andric   Locker py_lock(this,
2520435933ddSDimitry Andric                  Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
25214bb0738eSEd Maste 
25224bb0738eSEd Maste   static char callee_name[] = "get_type_name";
25234bb0738eSEd Maste 
25244bb0738eSEd Maste   ConstString ret_val;
25254bb0738eSEd Maste   bool got_string = false;
25264bb0738eSEd Maste   std::string buffer;
25274bb0738eSEd Maste 
25284bb0738eSEd Maste   if (!implementor_sp)
25294bb0738eSEd Maste     return ret_val;
25304bb0738eSEd Maste 
25314bb0738eSEd Maste   StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
25324bb0738eSEd Maste   if (!generic)
25334bb0738eSEd Maste     return ret_val;
2534435933ddSDimitry Andric   PythonObject implementor(PyRefType::Borrowed,
2535435933ddSDimitry Andric                            (PyObject *)generic->GetValue());
25364bb0738eSEd Maste   if (!implementor.IsAllocated())
25374bb0738eSEd Maste     return ret_val;
25384bb0738eSEd Maste 
2539435933ddSDimitry Andric   PythonObject pmeth(PyRefType::Owned,
2540435933ddSDimitry Andric                      PyObject_GetAttrString(implementor.get(), callee_name));
25414bb0738eSEd Maste 
25424bb0738eSEd Maste   if (PyErr_Occurred())
25434bb0738eSEd Maste     PyErr_Clear();
25444bb0738eSEd Maste 
25454bb0738eSEd Maste   if (!pmeth.IsAllocated())
25464bb0738eSEd Maste     return ret_val;
25474bb0738eSEd Maste 
2548435933ddSDimitry Andric   if (PyCallable_Check(pmeth.get()) == 0) {
25494bb0738eSEd Maste     if (PyErr_Occurred())
25504bb0738eSEd Maste       PyErr_Clear();
25514bb0738eSEd Maste     return ret_val;
25524bb0738eSEd Maste   }
25534bb0738eSEd Maste 
25544bb0738eSEd Maste   if (PyErr_Occurred())
25554bb0738eSEd Maste     PyErr_Clear();
25564bb0738eSEd Maste 
25574bb0738eSEd Maste   // right now we know this function exists and is callable..
2558435933ddSDimitry Andric   PythonObject py_return(
2559435933ddSDimitry Andric       PyRefType::Owned,
2560435933ddSDimitry Andric       PyObject_CallMethod(implementor.get(), callee_name, nullptr));
25614bb0738eSEd Maste 
25624bb0738eSEd Maste   // if it fails, print the error but otherwise go on
2563435933ddSDimitry Andric   if (PyErr_Occurred()) {
25644bb0738eSEd Maste     PyErr_Print();
25654bb0738eSEd Maste     PyErr_Clear();
25664bb0738eSEd Maste   }
25674bb0738eSEd Maste 
2568435933ddSDimitry Andric   if (py_return.IsAllocated() && PythonString::Check(py_return.get())) {
25694bb0738eSEd Maste     PythonString py_string(PyRefType::Borrowed, py_return.get());
25704bb0738eSEd Maste     llvm::StringRef return_data(py_string.GetString());
2571435933ddSDimitry Andric     if (!return_data.empty()) {
25724bb0738eSEd Maste       buffer.assign(return_data.data(), return_data.size());
25734bb0738eSEd Maste       got_string = true;
25744bb0738eSEd Maste     }
25754bb0738eSEd Maste   }
25764bb0738eSEd Maste 
25774bb0738eSEd Maste   if (got_string)
25784bb0738eSEd Maste     ret_val.SetCStringWithLength(buffer.c_str(), buffer.size());
25794bb0738eSEd Maste 
25804bb0738eSEd Maste   return ret_val;
25814bb0738eSEd Maste }
25824bb0738eSEd Maste 
RunScriptFormatKeyword(const char * impl_function,Process * process,std::string & output,Status & error)2583435933ddSDimitry Andric bool ScriptInterpreterPython::RunScriptFormatKeyword(const char *impl_function,
25849f2f44ceSEd Maste                                                      Process *process,
25859f2f44ceSEd Maste                                                      std::string &output,
25865517e702SDimitry Andric                                                      Status &error) {
25879f2f44ceSEd Maste   bool ret_val;
2588435933ddSDimitry Andric   if (!process) {
25899f2f44ceSEd Maste     error.SetErrorString("no process");
25909f2f44ceSEd Maste     return false;
25919f2f44ceSEd Maste   }
2592435933ddSDimitry Andric   if (!impl_function || !impl_function[0]) {
25939f2f44ceSEd Maste     error.SetErrorString("no function to execute");
25949f2f44ceSEd Maste     return false;
25959f2f44ceSEd Maste   }
2596435933ddSDimitry Andric   if (!g_swig_run_script_keyword_process) {
25979f2f44ceSEd Maste     error.SetErrorString("internal helper function missing");
25989f2f44ceSEd Maste     return false;
25999f2f44ceSEd Maste   }
26009f2f44ceSEd Maste   {
26019f2f44ceSEd Maste     ProcessSP process_sp(process->shared_from_this());
2602435933ddSDimitry Andric     Locker py_lock(this,
2603435933ddSDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2604435933ddSDimitry Andric     ret_val = g_swig_run_script_keyword_process(
2605435933ddSDimitry Andric         impl_function, m_dictionary_name.c_str(), process_sp, output);
26069f2f44ceSEd Maste     if (!ret_val)
26079f2f44ceSEd Maste       error.SetErrorString("python script evaluation failed");
26089f2f44ceSEd Maste   }
26099f2f44ceSEd Maste   return ret_val;
26109f2f44ceSEd Maste }
26119f2f44ceSEd Maste 
RunScriptFormatKeyword(const char * impl_function,Thread * thread,std::string & output,Status & error)2612435933ddSDimitry Andric bool ScriptInterpreterPython::RunScriptFormatKeyword(const char *impl_function,
26139f2f44ceSEd Maste                                                      Thread *thread,
26149f2f44ceSEd Maste                                                      std::string &output,
26155517e702SDimitry Andric                                                      Status &error) {
26169f2f44ceSEd Maste   bool ret_val;
2617435933ddSDimitry Andric   if (!thread) {
26189f2f44ceSEd Maste     error.SetErrorString("no thread");
26199f2f44ceSEd Maste     return false;
26209f2f44ceSEd Maste   }
2621435933ddSDimitry Andric   if (!impl_function || !impl_function[0]) {
26229f2f44ceSEd Maste     error.SetErrorString("no function to execute");
26239f2f44ceSEd Maste     return false;
26249f2f44ceSEd Maste   }
2625435933ddSDimitry Andric   if (!g_swig_run_script_keyword_thread) {
26269f2f44ceSEd Maste     error.SetErrorString("internal helper function missing");
26279f2f44ceSEd Maste     return false;
26289f2f44ceSEd Maste   }
26299f2f44ceSEd Maste   {
26309f2f44ceSEd Maste     ThreadSP thread_sp(thread->shared_from_this());
2631435933ddSDimitry Andric     Locker py_lock(this,
2632435933ddSDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2633435933ddSDimitry Andric     ret_val = g_swig_run_script_keyword_thread(
2634435933ddSDimitry Andric         impl_function, m_dictionary_name.c_str(), thread_sp, output);
26359f2f44ceSEd Maste     if (!ret_val)
26369f2f44ceSEd Maste       error.SetErrorString("python script evaluation failed");
26379f2f44ceSEd Maste   }
26389f2f44ceSEd Maste   return ret_val;
26399f2f44ceSEd Maste }
26409f2f44ceSEd Maste 
RunScriptFormatKeyword(const char * impl_function,Target * target,std::string & output,Status & error)2641435933ddSDimitry Andric bool ScriptInterpreterPython::RunScriptFormatKeyword(const char *impl_function,
26429f2f44ceSEd Maste                                                      Target *target,
26439f2f44ceSEd Maste                                                      std::string &output,
26445517e702SDimitry Andric                                                      Status &error) {
26459f2f44ceSEd Maste   bool ret_val;
2646435933ddSDimitry Andric   if (!target) {
26479f2f44ceSEd Maste     error.SetErrorString("no thread");
26489f2f44ceSEd Maste     return false;
26499f2f44ceSEd Maste   }
2650435933ddSDimitry Andric   if (!impl_function || !impl_function[0]) {
26519f2f44ceSEd Maste     error.SetErrorString("no function to execute");
26529f2f44ceSEd Maste     return false;
26539f2f44ceSEd Maste   }
2654435933ddSDimitry Andric   if (!g_swig_run_script_keyword_target) {
26559f2f44ceSEd Maste     error.SetErrorString("internal helper function missing");
26569f2f44ceSEd Maste     return false;
26579f2f44ceSEd Maste   }
26589f2f44ceSEd Maste   {
26599f2f44ceSEd Maste     TargetSP target_sp(target->shared_from_this());
2660435933ddSDimitry Andric     Locker py_lock(this,
2661435933ddSDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2662435933ddSDimitry Andric     ret_val = g_swig_run_script_keyword_target(
2663435933ddSDimitry Andric         impl_function, m_dictionary_name.c_str(), target_sp, output);
26649f2f44ceSEd Maste     if (!ret_val)
26659f2f44ceSEd Maste       error.SetErrorString("python script evaluation failed");
26669f2f44ceSEd Maste   }
26679f2f44ceSEd Maste   return ret_val;
26689f2f44ceSEd Maste }
26699f2f44ceSEd Maste 
RunScriptFormatKeyword(const char * impl_function,StackFrame * frame,std::string & output,Status & error)2670435933ddSDimitry Andric bool ScriptInterpreterPython::RunScriptFormatKeyword(const char *impl_function,
26719f2f44ceSEd Maste                                                      StackFrame *frame,
26729f2f44ceSEd Maste                                                      std::string &output,
26735517e702SDimitry Andric                                                      Status &error) {
26749f2f44ceSEd Maste   bool ret_val;
2675435933ddSDimitry Andric   if (!frame) {
26769f2f44ceSEd Maste     error.SetErrorString("no frame");
26779f2f44ceSEd Maste     return false;
26789f2f44ceSEd Maste   }
2679435933ddSDimitry Andric   if (!impl_function || !impl_function[0]) {
26809f2f44ceSEd Maste     error.SetErrorString("no function to execute");
26819f2f44ceSEd Maste     return false;
26829f2f44ceSEd Maste   }
2683435933ddSDimitry Andric   if (!g_swig_run_script_keyword_frame) {
26849f2f44ceSEd Maste     error.SetErrorString("internal helper function missing");
26859f2f44ceSEd Maste     return false;
26869f2f44ceSEd Maste   }
26879f2f44ceSEd Maste   {
26889f2f44ceSEd Maste     StackFrameSP frame_sp(frame->shared_from_this());
2689435933ddSDimitry Andric     Locker py_lock(this,
2690435933ddSDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2691435933ddSDimitry Andric     ret_val = g_swig_run_script_keyword_frame(
2692435933ddSDimitry Andric         impl_function, m_dictionary_name.c_str(), frame_sp, output);
26939f2f44ceSEd Maste     if (!ret_val)
26949f2f44ceSEd Maste       error.SetErrorString("python script evaluation failed");
26959f2f44ceSEd Maste   }
26969f2f44ceSEd Maste   return ret_val;
26979f2f44ceSEd Maste }
26989f2f44ceSEd Maste 
RunScriptFormatKeyword(const char * impl_function,ValueObject * value,std::string & output,Status & error)2699435933ddSDimitry Andric bool ScriptInterpreterPython::RunScriptFormatKeyword(const char *impl_function,
27009f2f44ceSEd Maste                                                      ValueObject *value,
27019f2f44ceSEd Maste                                                      std::string &output,
27025517e702SDimitry Andric                                                      Status &error) {
27039f2f44ceSEd Maste   bool ret_val;
2704435933ddSDimitry Andric   if (!value) {
27059f2f44ceSEd Maste     error.SetErrorString("no value");
27069f2f44ceSEd Maste     return false;
27079f2f44ceSEd Maste   }
2708435933ddSDimitry Andric   if (!impl_function || !impl_function[0]) {
27099f2f44ceSEd Maste     error.SetErrorString("no function to execute");
27109f2f44ceSEd Maste     return false;
27119f2f44ceSEd Maste   }
2712435933ddSDimitry Andric   if (!g_swig_run_script_keyword_value) {
27139f2f44ceSEd Maste     error.SetErrorString("internal helper function missing");
27149f2f44ceSEd Maste     return false;
27159f2f44ceSEd Maste   }
27169f2f44ceSEd Maste   {
27179f2f44ceSEd Maste     ValueObjectSP value_sp(value->GetSP());
2718435933ddSDimitry Andric     Locker py_lock(this,
2719435933ddSDimitry Andric                    Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2720435933ddSDimitry Andric     ret_val = g_swig_run_script_keyword_value(
2721435933ddSDimitry Andric         impl_function, m_dictionary_name.c_str(), value_sp, output);
27229f2f44ceSEd Maste     if (!ret_val)
27239f2f44ceSEd Maste       error.SetErrorString("python script evaluation failed");
27249f2f44ceSEd Maste   }
27259f2f44ceSEd Maste   return ret_val;
27269f2f44ceSEd Maste }
27279f2f44ceSEd Maste 
replace_all(std::string & str,const std::string & oldStr,const std::string & newStr)2728435933ddSDimitry Andric uint64_t replace_all(std::string &str, const std::string &oldStr,
2729435933ddSDimitry Andric                      const std::string &newStr) {
27309f2f44ceSEd Maste   size_t pos = 0;
27319f2f44ceSEd Maste   uint64_t matches = 0;
2732435933ddSDimitry Andric   while ((pos = str.find(oldStr, pos)) != std::string::npos) {
27339f2f44ceSEd Maste     matches++;
27349f2f44ceSEd Maste     str.replace(pos, oldStr.length(), newStr);
27359f2f44ceSEd Maste     pos += newStr.length();
27369f2f44ceSEd Maste   }
27379f2f44ceSEd Maste   return matches;
27389f2f44ceSEd Maste }
27399f2f44ceSEd Maste 
LoadScriptingModule(const char * pathname,bool can_reload,bool init_session,lldb_private::Status & error,StructuredData::ObjectSP * module_sp)2740435933ddSDimitry Andric bool ScriptInterpreterPython::LoadScriptingModule(
2741435933ddSDimitry Andric     const char *pathname, bool can_reload, bool init_session,
27425517e702SDimitry Andric     lldb_private::Status &error, StructuredData::ObjectSP *module_sp) {
2743435933ddSDimitry Andric   if (!pathname || !pathname[0]) {
27449f2f44ceSEd Maste     error.SetErrorString("invalid pathname");
27459f2f44ceSEd Maste     return false;
27469f2f44ceSEd Maste   }
27479f2f44ceSEd Maste 
2748435933ddSDimitry Andric   if (!g_swig_call_module_init) {
27499f2f44ceSEd Maste     error.SetErrorString("internal helper function missing");
27509f2f44ceSEd Maste     return false;
27519f2f44ceSEd Maste   }
27529f2f44ceSEd Maste 
27539f2f44ceSEd Maste   lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();
27549f2f44ceSEd Maste 
27559f2f44ceSEd Maste   {
2756*b5893f02SDimitry Andric     FileSpec target_file(pathname);
2757*b5893f02SDimitry Andric     FileSystem::Instance().Resolve(target_file);
27589f2f44ceSEd Maste     std::string basename(target_file.GetFilename().GetCString());
27599f2f44ceSEd Maste 
27609f2f44ceSEd Maste     StreamString command_stream;
27619f2f44ceSEd Maste 
27624bb0738eSEd Maste     // Before executing Python code, lock the GIL.
2763435933ddSDimitry Andric     Locker py_lock(this, Locker::AcquireLock |
2764435933ddSDimitry Andric                              (init_session ? Locker::InitSession : 0) |
2765435933ddSDimitry Andric                              Locker::NoSTDIN,
2766435933ddSDimitry Andric                    Locker::FreeAcquiredLock |
2767435933ddSDimitry Andric                        (init_session ? Locker::TearDownSession : 0));
2768f678e45dSDimitry Andric     namespace fs = llvm::sys::fs;
2769f678e45dSDimitry Andric     fs::file_status st;
2770f678e45dSDimitry Andric     std::error_code ec = status(target_file.GetPath(), st);
27719f2f44ceSEd Maste 
2772f678e45dSDimitry Andric     if (ec || st.type() == fs::file_type::status_error ||
2773f678e45dSDimitry Andric         st.type() == fs::file_type::type_unknown ||
2774f678e45dSDimitry Andric         st.type() == fs::file_type::file_not_found) {
27759f2f44ceSEd Maste       // if not a valid file of any sort, check if it might be a filename still
27769f2f44ceSEd Maste       // dot can't be used but / and \ can, and if either is found, reject
2777435933ddSDimitry Andric       if (strchr(pathname, '\\') || strchr(pathname, '/')) {
27789f2f44ceSEd Maste         error.SetErrorString("invalid pathname");
27799f2f44ceSEd Maste         return false;
27809f2f44ceSEd Maste       }
2781435933ddSDimitry Andric       basename = pathname; // not a filename, probably a package of some sort,
2782435933ddSDimitry Andric                            // let it go through
2783f678e45dSDimitry Andric     } else if (is_directory(st) || is_regular_file(st)) {
27844bb0738eSEd Maste       std::string directory = target_file.GetDirectory().GetCString();
27854bb0738eSEd Maste       replace_all(directory, "\\", "\\\\");
27869f2f44ceSEd Maste       replace_all(directory, "'", "\\'");
27879f2f44ceSEd Maste 
27889f2f44ceSEd Maste       // now make sure that Python has "directory" in the search path
27899f2f44ceSEd Maste       StreamString command_stream;
2790435933ddSDimitry Andric       command_stream.Printf("if not (sys.path.__contains__('%s')):\n    "
2791435933ddSDimitry Andric                             "sys.path.insert(1,'%s');\n\n",
2792435933ddSDimitry Andric                             directory.c_str(), directory.c_str());
2793435933ddSDimitry Andric       bool syspath_retval =
2794435933ddSDimitry Andric           ExecuteMultipleLines(command_stream.GetData(),
2795435933ddSDimitry Andric                                ScriptInterpreter::ExecuteScriptOptions()
2796435933ddSDimitry Andric                                    .SetEnableIO(false)
2797435933ddSDimitry Andric                                    .SetSetLLDBGlobals(false))
2798435933ddSDimitry Andric               .Success();
2799435933ddSDimitry Andric       if (!syspath_retval) {
28009f2f44ceSEd Maste         error.SetErrorString("Python sys.path handling failed");
28019f2f44ceSEd Maste         return false;
28029f2f44ceSEd Maste       }
28039f2f44ceSEd Maste 
28049f2f44ceSEd Maste       // strip .py or .pyc extension
28059f2f44ceSEd Maste       ConstString extension = target_file.GetFileNameExtension();
2806435933ddSDimitry Andric       if (extension) {
28074ba319b5SDimitry Andric         if (llvm::StringRef(extension.GetCString()) == ".py")
28089f2f44ceSEd Maste           basename.resize(basename.length() - 3);
28094ba319b5SDimitry Andric         else if (llvm::StringRef(extension.GetCString()) == ".pyc")
28109f2f44ceSEd Maste           basename.resize(basename.length() - 4);
28119f2f44ceSEd Maste       }
2812435933ddSDimitry Andric     } else {
28139f2f44ceSEd Maste       error.SetErrorString("no known way to import this module specification");
28149f2f44ceSEd Maste       return false;
28159f2f44ceSEd Maste     }
28169f2f44ceSEd Maste 
28179f2f44ceSEd Maste     // check if the module is already import-ed
28189f2f44ceSEd Maste     command_stream.Clear();
28199f2f44ceSEd Maste     command_stream.Printf("sys.modules.__contains__('%s')", basename.c_str());
28209f2f44ceSEd Maste     bool does_contain = false;
28214ba319b5SDimitry Andric     // this call will succeed if the module was ever imported in any Debugger
28224ba319b5SDimitry Andric     // in the lifetime of the process in which this LLDB framework is living
2823435933ddSDimitry Andric     bool was_imported_globally =
2824435933ddSDimitry Andric         (ExecuteOneLineWithReturn(
2825435933ddSDimitry Andric              command_stream.GetData(),
2826435933ddSDimitry Andric              ScriptInterpreterPython::eScriptReturnTypeBool, &does_contain,
2827435933ddSDimitry Andric              ScriptInterpreter::ExecuteScriptOptions()
2828435933ddSDimitry Andric                  .SetEnableIO(false)
2829435933ddSDimitry Andric                  .SetSetLLDBGlobals(false)) &&
2830435933ddSDimitry Andric          does_contain);
2831435933ddSDimitry Andric     // this call will fail if the module was not imported in this Debugger
2832435933ddSDimitry Andric     // before
28339f2f44ceSEd Maste     command_stream.Clear();
28349f2f44ceSEd Maste     command_stream.Printf("sys.getrefcount(%s)", basename.c_str());
2835435933ddSDimitry Andric     bool was_imported_locally = GetSessionDictionary()
2836435933ddSDimitry Andric                                     .GetItemForKey(PythonString(basename))
2837435933ddSDimitry Andric                                     .IsAllocated();
28389f2f44ceSEd Maste 
28399f2f44ceSEd Maste     bool was_imported = (was_imported_globally || was_imported_locally);
28409f2f44ceSEd Maste 
2841*b5893f02SDimitry Andric     if (was_imported && !can_reload) {
28429f2f44ceSEd Maste       error.SetErrorString("module already imported");
28439f2f44ceSEd Maste       return false;
28449f2f44ceSEd Maste     }
28459f2f44ceSEd Maste 
28469f2f44ceSEd Maste     // now actually do the import
28479f2f44ceSEd Maste     command_stream.Clear();
28489f2f44ceSEd Maste 
2849435933ddSDimitry Andric     if (was_imported) {
28509f2f44ceSEd Maste       if (!was_imported_locally)
2851435933ddSDimitry Andric         command_stream.Printf("import %s ; reload_module(%s)", basename.c_str(),
2852435933ddSDimitry Andric                               basename.c_str());
28539f2f44ceSEd Maste       else
28549f2f44ceSEd Maste         command_stream.Printf("reload_module(%s)", basename.c_str());
2855435933ddSDimitry Andric     } else
28569f2f44ceSEd Maste       command_stream.Printf("import %s", basename.c_str());
28579f2f44ceSEd Maste 
2858435933ddSDimitry Andric     error = ExecuteMultipleLines(command_stream.GetData(),
2859435933ddSDimitry Andric                                  ScriptInterpreter::ExecuteScriptOptions()
2860435933ddSDimitry Andric                                      .SetEnableIO(false)
2861435933ddSDimitry Andric                                      .SetSetLLDBGlobals(false));
28629f2f44ceSEd Maste     if (error.Fail())
28639f2f44ceSEd Maste       return false;
28649f2f44ceSEd Maste 
28659f2f44ceSEd Maste     // if we are here, everything worked
28669f2f44ceSEd Maste     // call __lldb_init_module(debugger,dict)
2867435933ddSDimitry Andric     if (!g_swig_call_module_init(basename.c_str(), m_dictionary_name.c_str(),
2868435933ddSDimitry Andric                                  debugger_sp)) {
28699f2f44ceSEd Maste       error.SetErrorString("calling __lldb_init_module failed");
28709f2f44ceSEd Maste       return false;
28719f2f44ceSEd Maste     }
28729f2f44ceSEd Maste 
2873435933ddSDimitry Andric     if (module_sp) {
28749f2f44ceSEd Maste       // everything went just great, now set the module object
28759f2f44ceSEd Maste       command_stream.Clear();
28769f2f44ceSEd Maste       command_stream.Printf("%s", basename.c_str());
28779f2f44ceSEd Maste       void *module_pyobj = nullptr;
2878435933ddSDimitry Andric       if (ExecuteOneLineWithReturn(
2879435933ddSDimitry Andric               command_stream.GetData(),
2880435933ddSDimitry Andric               ScriptInterpreter::eScriptReturnTypeOpaqueObject,
2881435933ddSDimitry Andric               &module_pyobj) &&
2882435933ddSDimitry Andric           module_pyobj)
28839f2f44ceSEd Maste         module_sp->reset(new StructuredPythonObject(module_pyobj));
28849f2f44ceSEd Maste     }
28859f2f44ceSEd Maste 
28869f2f44ceSEd Maste     return true;
28879f2f44ceSEd Maste   }
28889f2f44ceSEd Maste }
28899f2f44ceSEd Maste 
IsReservedWord(const char * word)2890435933ddSDimitry Andric bool ScriptInterpreterPython::IsReservedWord(const char *word) {
28919f2f44ceSEd Maste   if (!word || !word[0])
28929f2f44ceSEd Maste     return false;
28939f2f44ceSEd Maste 
28949f2f44ceSEd Maste   llvm::StringRef word_sr(word);
28959f2f44ceSEd Maste 
28964ba319b5SDimitry Andric   // filter out a few characters that would just confuse us and that are
28974ba319b5SDimitry Andric   // clearly not keyword material anyway
28989f2f44ceSEd Maste   if (word_sr.find_first_of("'\"") != llvm::StringRef::npos)
28999f2f44ceSEd Maste     return false;
29009f2f44ceSEd Maste 
29019f2f44ceSEd Maste   StreamString command_stream;
29029f2f44ceSEd Maste   command_stream.Printf("keyword.iskeyword('%s')", word);
29039f2f44ceSEd Maste   bool result;
29049f2f44ceSEd Maste   ExecuteScriptOptions options;
29059f2f44ceSEd Maste   options.SetEnableIO(false);
29069f2f44ceSEd Maste   options.SetMaskoutErrors(true);
29079f2f44ceSEd Maste   options.SetSetLLDBGlobals(false);
2908435933ddSDimitry Andric   if (ExecuteOneLineWithReturn(command_stream.GetData(),
2909435933ddSDimitry Andric                                ScriptInterpreter::eScriptReturnTypeBool,
2910435933ddSDimitry Andric                                &result, options))
29119f2f44ceSEd Maste     return result;
29129f2f44ceSEd Maste   return false;
29139f2f44ceSEd Maste }
29149f2f44ceSEd Maste 
SynchronicityHandler(lldb::DebuggerSP debugger_sp,ScriptedCommandSynchronicity synchro)2915435933ddSDimitry Andric ScriptInterpreterPython::SynchronicityHandler::SynchronicityHandler(
2916435933ddSDimitry Andric     lldb::DebuggerSP debugger_sp, ScriptedCommandSynchronicity synchro)
2917435933ddSDimitry Andric     : m_debugger_sp(debugger_sp), m_synch_wanted(synchro),
2918435933ddSDimitry Andric       m_old_asynch(debugger_sp->GetAsyncExecution()) {
29199f2f44ceSEd Maste   if (m_synch_wanted == eScriptedCommandSynchronicitySynchronous)
29209f2f44ceSEd Maste     m_debugger_sp->SetAsyncExecution(false);
29219f2f44ceSEd Maste   else if (m_synch_wanted == eScriptedCommandSynchronicityAsynchronous)
29229f2f44ceSEd Maste     m_debugger_sp->SetAsyncExecution(true);
29239f2f44ceSEd Maste }
29249f2f44ceSEd Maste 
~SynchronicityHandler()2925435933ddSDimitry Andric ScriptInterpreterPython::SynchronicityHandler::~SynchronicityHandler() {
29269f2f44ceSEd Maste   if (m_synch_wanted != eScriptedCommandSynchronicityCurrentValue)
29279f2f44ceSEd Maste     m_debugger_sp->SetAsyncExecution(m_old_asynch);
29289f2f44ceSEd Maste }
29299f2f44ceSEd Maste 
RunScriptBasedCommand(const char * impl_function,llvm::StringRef args,ScriptedCommandSynchronicity synchronicity,lldb_private::CommandReturnObject & cmd_retobj,Status & error,const lldb_private::ExecutionContext & exe_ctx)2930435933ddSDimitry Andric bool ScriptInterpreterPython::RunScriptBasedCommand(
29314ba319b5SDimitry Andric     const char *impl_function, llvm::StringRef args,
29329f2f44ceSEd Maste     ScriptedCommandSynchronicity synchronicity,
29335517e702SDimitry Andric     lldb_private::CommandReturnObject &cmd_retobj, Status &error,
2934435933ddSDimitry Andric     const lldb_private::ExecutionContext &exe_ctx) {
2935435933ddSDimitry Andric   if (!impl_function) {
29369f2f44ceSEd Maste     error.SetErrorString("no function to execute");
29379f2f44ceSEd Maste     return false;
29389f2f44ceSEd Maste   }
29399f2f44ceSEd Maste 
2940435933ddSDimitry Andric   if (!g_swig_call_command) {
29419f2f44ceSEd Maste     error.SetErrorString("no helper function to run scripted commands");
29429f2f44ceSEd Maste     return false;
29439f2f44ceSEd Maste   }
29449f2f44ceSEd Maste 
29459f2f44ceSEd Maste   lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();
29469f2f44ceSEd Maste   lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
29479f2f44ceSEd Maste 
2948435933ddSDimitry Andric   if (!debugger_sp.get()) {
29499f2f44ceSEd Maste     error.SetErrorString("invalid Debugger pointer");
29509f2f44ceSEd Maste     return false;
29519f2f44ceSEd Maste   }
29529f2f44ceSEd Maste 
29539f2f44ceSEd Maste   bool ret_val = false;
29549f2f44ceSEd Maste 
29559f2f44ceSEd Maste   std::string err_msg;
29569f2f44ceSEd Maste 
29579f2f44ceSEd Maste   {
29589f2f44ceSEd Maste     Locker py_lock(this,
2959435933ddSDimitry Andric                    Locker::AcquireLock | Locker::InitSession |
2960435933ddSDimitry Andric                        (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
29619f2f44ceSEd Maste                    Locker::FreeLock | Locker::TearDownSession);
29629f2f44ceSEd Maste 
2963435933ddSDimitry Andric     SynchronicityHandler synch_handler(debugger_sp, synchronicity);
29649f2f44ceSEd Maste 
29654ba319b5SDimitry Andric     std::string args_str = args.str();
29664ba319b5SDimitry Andric     ret_val = g_swig_call_command(impl_function, m_dictionary_name.c_str(),
29674ba319b5SDimitry Andric                                   debugger_sp, args_str.c_str(), cmd_retobj,
29684ba319b5SDimitry Andric                                   exe_ctx_ref_sp);
29699f2f44ceSEd Maste   }
29709f2f44ceSEd Maste 
29719f2f44ceSEd Maste   if (!ret_val)
29729f2f44ceSEd Maste     error.SetErrorString("unable to execute script function");
29739f2f44ceSEd Maste   else
29749f2f44ceSEd Maste     error.Clear();
29759f2f44ceSEd Maste 
29769f2f44ceSEd Maste   return ret_val;
29779f2f44ceSEd Maste }
29789f2f44ceSEd Maste 
RunScriptBasedCommand(StructuredData::GenericSP impl_obj_sp,llvm::StringRef args,ScriptedCommandSynchronicity synchronicity,lldb_private::CommandReturnObject & cmd_retobj,Status & error,const lldb_private::ExecutionContext & exe_ctx)2979435933ddSDimitry Andric bool ScriptInterpreterPython::RunScriptBasedCommand(
29804ba319b5SDimitry Andric     StructuredData::GenericSP impl_obj_sp, llvm::StringRef args,
29819f2f44ceSEd Maste     ScriptedCommandSynchronicity synchronicity,
29825517e702SDimitry Andric     lldb_private::CommandReturnObject &cmd_retobj, Status &error,
2983435933ddSDimitry Andric     const lldb_private::ExecutionContext &exe_ctx) {
2984435933ddSDimitry Andric   if (!impl_obj_sp || !impl_obj_sp->IsValid()) {
29859f2f44ceSEd Maste     error.SetErrorString("no function to execute");
29869f2f44ceSEd Maste     return false;
29879f2f44ceSEd Maste   }
29889f2f44ceSEd Maste 
2989435933ddSDimitry Andric   if (!g_swig_call_command_object) {
29909f2f44ceSEd Maste     error.SetErrorString("no helper function to run scripted commands");
29919f2f44ceSEd Maste     return false;
29929f2f44ceSEd Maste   }
29939f2f44ceSEd Maste 
29949f2f44ceSEd Maste   lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();
29959f2f44ceSEd Maste   lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
29969f2f44ceSEd Maste 
2997435933ddSDimitry Andric   if (!debugger_sp.get()) {
29989f2f44ceSEd Maste     error.SetErrorString("invalid Debugger pointer");
29999f2f44ceSEd Maste     return false;
30009f2f44ceSEd Maste   }
30019f2f44ceSEd Maste 
30029f2f44ceSEd Maste   bool ret_val = false;
30039f2f44ceSEd Maste 
30049f2f44ceSEd Maste   std::string err_msg;
30059f2f44ceSEd Maste 
30069f2f44ceSEd Maste   {
30079f2f44ceSEd Maste     Locker py_lock(this,
3008435933ddSDimitry Andric                    Locker::AcquireLock | Locker::InitSession |
3009435933ddSDimitry Andric                        (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
30109f2f44ceSEd Maste                    Locker::FreeLock | Locker::TearDownSession);
30119f2f44ceSEd Maste 
3012435933ddSDimitry Andric     SynchronicityHandler synch_handler(debugger_sp, synchronicity);
30139f2f44ceSEd Maste 
30144ba319b5SDimitry Andric     std::string args_str = args.str();
3015435933ddSDimitry Andric     ret_val = g_swig_call_command_object(impl_obj_sp->GetValue(), debugger_sp,
30164ba319b5SDimitry Andric                                          args_str.c_str(), cmd_retobj,
30174ba319b5SDimitry Andric                                          exe_ctx_ref_sp);
30189f2f44ceSEd Maste   }
30199f2f44ceSEd Maste 
30209f2f44ceSEd Maste   if (!ret_val)
30219f2f44ceSEd Maste     error.SetErrorString("unable to execute script function");
30229f2f44ceSEd Maste   else
30239f2f44ceSEd Maste     error.Clear();
30249f2f44ceSEd Maste 
30259f2f44ceSEd Maste   return ret_val;
30269f2f44ceSEd Maste }
30279f2f44ceSEd Maste 
30284ba319b5SDimitry Andric // in Python, a special attribute __doc__ contains the docstring for an object
30294ba319b5SDimitry Andric // (function, method, class, ...) if any is defined Otherwise, the attribute's
30304ba319b5SDimitry Andric // value is None
GetDocumentationForItem(const char * item,std::string & dest)3031435933ddSDimitry Andric bool ScriptInterpreterPython::GetDocumentationForItem(const char *item,
3032435933ddSDimitry Andric                                                       std::string &dest) {
30339f2f44ceSEd Maste   dest.clear();
30349f2f44ceSEd Maste   if (!item || !*item)
30359f2f44ceSEd Maste     return false;
30369f2f44ceSEd Maste   std::string command(item);
30379f2f44ceSEd Maste   command += ".__doc__";
30389f2f44ceSEd Maste 
3039435933ddSDimitry Andric   char *result_ptr = nullptr; // Python is going to point this to valid data if
3040435933ddSDimitry Andric                               // ExecuteOneLineWithReturn returns successfully
30419f2f44ceSEd Maste 
3042435933ddSDimitry Andric   if (ExecuteOneLineWithReturn(
3043435933ddSDimitry Andric           command.c_str(), ScriptInterpreter::eScriptReturnTypeCharStrOrNone,
30449f2f44ceSEd Maste           &result_ptr,
3045435933ddSDimitry Andric           ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false))) {
30469f2f44ceSEd Maste     if (result_ptr)
30479f2f44ceSEd Maste       dest.assign(result_ptr);
30489f2f44ceSEd Maste     return true;
3049435933ddSDimitry Andric   } else {
30509f2f44ceSEd Maste     StreamString str_stream;
3051435933ddSDimitry Andric     str_stream.Printf(
3052435933ddSDimitry Andric         "Function %s was not found. Containing module might be missing.", item);
3053435933ddSDimitry Andric     dest = str_stream.GetString();
30549f2f44ceSEd Maste     return false;
30559f2f44ceSEd Maste   }
30569f2f44ceSEd Maste }
30579f2f44ceSEd Maste 
GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,std::string & dest)3058435933ddSDimitry Andric bool ScriptInterpreterPython::GetShortHelpForCommandObject(
3059435933ddSDimitry Andric     StructuredData::GenericSP cmd_obj_sp, std::string &dest) {
30609f2f44ceSEd Maste   bool got_string = false;
30619f2f44ceSEd Maste   dest.clear();
30629f2f44ceSEd Maste 
3063435933ddSDimitry Andric   Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
30649f2f44ceSEd Maste 
30659f2f44ceSEd Maste   static char callee_name[] = "get_short_help";
30669f2f44ceSEd Maste 
30679f2f44ceSEd Maste   if (!cmd_obj_sp)
30689f2f44ceSEd Maste     return false;
30699f2f44ceSEd Maste 
3070435933ddSDimitry Andric   PythonObject implementor(PyRefType::Borrowed,
3071435933ddSDimitry Andric                            (PyObject *)cmd_obj_sp->GetValue());
30729f2f44ceSEd Maste 
30739f2f44ceSEd Maste   if (!implementor.IsAllocated())
30749f2f44ceSEd Maste     return false;
30759f2f44ceSEd Maste 
3076435933ddSDimitry Andric   PythonObject pmeth(PyRefType::Owned,
3077435933ddSDimitry Andric                      PyObject_GetAttrString(implementor.get(), callee_name));
30789f2f44ceSEd Maste 
30799f2f44ceSEd Maste   if (PyErr_Occurred())
30809f2f44ceSEd Maste     PyErr_Clear();
30819f2f44ceSEd Maste 
30829f2f44ceSEd Maste   if (!pmeth.IsAllocated())
30839f2f44ceSEd Maste     return false;
30849f2f44ceSEd Maste 
3085435933ddSDimitry Andric   if (PyCallable_Check(pmeth.get()) == 0) {
30869f2f44ceSEd Maste     if (PyErr_Occurred())
30879f2f44ceSEd Maste       PyErr_Clear();
30889f2f44ceSEd Maste     return false;
30899f2f44ceSEd Maste   }
30909f2f44ceSEd Maste 
30919f2f44ceSEd Maste   if (PyErr_Occurred())
30929f2f44ceSEd Maste     PyErr_Clear();
30939f2f44ceSEd Maste 
30949f2f44ceSEd Maste   // right now we know this function exists and is callable..
3095435933ddSDimitry Andric   PythonObject py_return(
3096435933ddSDimitry Andric       PyRefType::Owned,
3097435933ddSDimitry Andric       PyObject_CallMethod(implementor.get(), callee_name, nullptr));
30989f2f44ceSEd Maste 
30999f2f44ceSEd Maste   // if it fails, print the error but otherwise go on
3100435933ddSDimitry Andric   if (PyErr_Occurred()) {
31019f2f44ceSEd Maste     PyErr_Print();
31029f2f44ceSEd Maste     PyErr_Clear();
31039f2f44ceSEd Maste   }
31049f2f44ceSEd Maste 
3105435933ddSDimitry Andric   if (py_return.IsAllocated() && PythonString::Check(py_return.get())) {
31069f2f44ceSEd Maste     PythonString py_string(PyRefType::Borrowed, py_return.get());
31079f2f44ceSEd Maste     llvm::StringRef return_data(py_string.GetString());
31089f2f44ceSEd Maste     dest.assign(return_data.data(), return_data.size());
31099f2f44ceSEd Maste     got_string = true;
31109f2f44ceSEd Maste   }
31119f2f44ceSEd Maste   return got_string;
31129f2f44ceSEd Maste }
31139f2f44ceSEd Maste 
GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp)3114435933ddSDimitry Andric uint32_t ScriptInterpreterPython::GetFlagsForCommandObject(
3115435933ddSDimitry Andric     StructuredData::GenericSP cmd_obj_sp) {
31169f2f44ceSEd Maste   uint32_t result = 0;
31179f2f44ceSEd Maste 
3118435933ddSDimitry Andric   Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
31199f2f44ceSEd Maste 
31209f2f44ceSEd Maste   static char callee_name[] = "get_flags";
31219f2f44ceSEd Maste 
31229f2f44ceSEd Maste   if (!cmd_obj_sp)
31239f2f44ceSEd Maste     return result;
31249f2f44ceSEd Maste 
3125435933ddSDimitry Andric   PythonObject implementor(PyRefType::Borrowed,
3126435933ddSDimitry Andric                            (PyObject *)cmd_obj_sp->GetValue());
31279f2f44ceSEd Maste 
31289f2f44ceSEd Maste   if (!implementor.IsAllocated())
31299f2f44ceSEd Maste     return result;
31309f2f44ceSEd Maste 
3131435933ddSDimitry Andric   PythonObject pmeth(PyRefType::Owned,
3132435933ddSDimitry Andric                      PyObject_GetAttrString(implementor.get(), callee_name));
31339f2f44ceSEd Maste 
31349f2f44ceSEd Maste   if (PyErr_Occurred())
31359f2f44ceSEd Maste     PyErr_Clear();
31369f2f44ceSEd Maste 
31379f2f44ceSEd Maste   if (!pmeth.IsAllocated())
31389f2f44ceSEd Maste     return result;
31399f2f44ceSEd Maste 
3140435933ddSDimitry Andric   if (PyCallable_Check(pmeth.get()) == 0) {
31419f2f44ceSEd Maste     if (PyErr_Occurred())
31429f2f44ceSEd Maste       PyErr_Clear();
31439f2f44ceSEd Maste     return result;
31449f2f44ceSEd Maste   }
31459f2f44ceSEd Maste 
31469f2f44ceSEd Maste   if (PyErr_Occurred())
31479f2f44ceSEd Maste     PyErr_Clear();
31489f2f44ceSEd Maste 
31499f2f44ceSEd Maste   // right now we know this function exists and is callable..
3150435933ddSDimitry Andric   PythonObject py_return(
3151435933ddSDimitry Andric       PyRefType::Owned,
3152435933ddSDimitry Andric       PyObject_CallMethod(implementor.get(), callee_name, nullptr));
31539f2f44ceSEd Maste 
31549f2f44ceSEd Maste   // if it fails, print the error but otherwise go on
3155435933ddSDimitry Andric   if (PyErr_Occurred()) {
31569f2f44ceSEd Maste     PyErr_Print();
31579f2f44ceSEd Maste     PyErr_Clear();
31589f2f44ceSEd Maste   }
31599f2f44ceSEd Maste 
3160435933ddSDimitry Andric   if (py_return.IsAllocated() && PythonInteger::Check(py_return.get())) {
31619f2f44ceSEd Maste     PythonInteger int_value(PyRefType::Borrowed, py_return.get());
31629f2f44ceSEd Maste     result = int_value.GetInteger();
31639f2f44ceSEd Maste   }
31649f2f44ceSEd Maste 
31659f2f44ceSEd Maste   return result;
31669f2f44ceSEd Maste }
31679f2f44ceSEd Maste 
GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,std::string & dest)3168435933ddSDimitry Andric bool ScriptInterpreterPython::GetLongHelpForCommandObject(
3169435933ddSDimitry Andric     StructuredData::GenericSP cmd_obj_sp, std::string &dest) {
31709f2f44ceSEd Maste   bool got_string = false;
31719f2f44ceSEd Maste   dest.clear();
31729f2f44ceSEd Maste 
3173435933ddSDimitry Andric   Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
31749f2f44ceSEd Maste 
31759f2f44ceSEd Maste   static char callee_name[] = "get_long_help";
31769f2f44ceSEd Maste 
31779f2f44ceSEd Maste   if (!cmd_obj_sp)
31789f2f44ceSEd Maste     return false;
31799f2f44ceSEd Maste 
3180435933ddSDimitry Andric   PythonObject implementor(PyRefType::Borrowed,
3181435933ddSDimitry Andric                            (PyObject *)cmd_obj_sp->GetValue());
31829f2f44ceSEd Maste 
31839f2f44ceSEd Maste   if (!implementor.IsAllocated())
31849f2f44ceSEd Maste     return false;
31859f2f44ceSEd Maste 
3186435933ddSDimitry Andric   PythonObject pmeth(PyRefType::Owned,
3187435933ddSDimitry Andric                      PyObject_GetAttrString(implementor.get(), callee_name));
31889f2f44ceSEd Maste 
31899f2f44ceSEd Maste   if (PyErr_Occurred())
31909f2f44ceSEd Maste     PyErr_Clear();
31919f2f44ceSEd Maste 
31929f2f44ceSEd Maste   if (!pmeth.IsAllocated())
31939f2f44ceSEd Maste     return false;
31949f2f44ceSEd Maste 
3195435933ddSDimitry Andric   if (PyCallable_Check(pmeth.get()) == 0) {
31969f2f44ceSEd Maste     if (PyErr_Occurred())
31979f2f44ceSEd Maste       PyErr_Clear();
31989f2f44ceSEd Maste 
31999f2f44ceSEd Maste     return false;
32009f2f44ceSEd Maste   }
32019f2f44ceSEd Maste 
32029f2f44ceSEd Maste   if (PyErr_Occurred())
32039f2f44ceSEd Maste     PyErr_Clear();
32049f2f44ceSEd Maste 
32059f2f44ceSEd Maste   // right now we know this function exists and is callable..
3206435933ddSDimitry Andric   PythonObject py_return(
3207435933ddSDimitry Andric       PyRefType::Owned,
3208435933ddSDimitry Andric       PyObject_CallMethod(implementor.get(), callee_name, nullptr));
32099f2f44ceSEd Maste 
32109f2f44ceSEd Maste   // if it fails, print the error but otherwise go on
3211435933ddSDimitry Andric   if (PyErr_Occurred()) {
32129f2f44ceSEd Maste     PyErr_Print();
32139f2f44ceSEd Maste     PyErr_Clear();
32149f2f44ceSEd Maste   }
32159f2f44ceSEd Maste 
3216435933ddSDimitry Andric   if (py_return.IsAllocated() && PythonString::Check(py_return.get())) {
32179f2f44ceSEd Maste     PythonString str(PyRefType::Borrowed, py_return.get());
32189f2f44ceSEd Maste     llvm::StringRef str_data(str.GetString());
32199f2f44ceSEd Maste     dest.assign(str_data.data(), str_data.size());
32209f2f44ceSEd Maste     got_string = true;
32219f2f44ceSEd Maste   }
32229f2f44ceSEd Maste 
32239f2f44ceSEd Maste   return got_string;
32249f2f44ceSEd Maste }
32259f2f44ceSEd Maste 
32269f2f44ceSEd Maste std::unique_ptr<ScriptInterpreterLocker>
AcquireInterpreterLock()3227435933ddSDimitry Andric ScriptInterpreterPython::AcquireInterpreterLock() {
3228435933ddSDimitry Andric   std::unique_ptr<ScriptInterpreterLocker> py_lock(new Locker(
3229435933ddSDimitry Andric       this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN,
32309f2f44ceSEd Maste       Locker::FreeLock | Locker::TearDownSession));
32319f2f44ceSEd Maste   return py_lock;
32329f2f44ceSEd Maste }
32339f2f44ceSEd Maste 
InitializeInterpreter(SWIGInitCallback swig_init_callback,SWIGBreakpointCallbackFunction swig_breakpoint_callback,SWIGWatchpointCallbackFunction swig_watchpoint_callback,SWIGPythonTypeScriptCallbackFunction swig_typescript_callback,SWIGPythonCreateSyntheticProvider swig_synthetic_script,SWIGPythonCreateCommandObject swig_create_cmd,SWIGPythonCalculateNumChildren swig_calc_children,SWIGPythonGetChildAtIndex swig_get_child_index,SWIGPythonGetIndexOfChildWithName swig_get_index_child,SWIGPythonCastPyObjectToSBValue swig_cast_to_sbvalue,SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue,SWIGPythonUpdateSynthProviderInstance swig_update_provider,SWIGPythonMightHaveChildrenSynthProviderInstance swig_mighthavechildren_provider,SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider,SWIGPythonCallCommand swig_call_command,SWIGPythonCallCommandObject swig_call_command_object,SWIGPythonCallModuleInit swig_call_module_init,SWIGPythonCreateOSPlugin swig_create_os_plugin,SWIGPythonCreateFrameRecognizer swig_create_frame_recognizer,SWIGPythonGetRecognizedArguments swig_get_recognized_arguments,SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,SWIGPython_GetDynamicSetting swig_plugin_get,SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,SWIGPythonCallThreadPlan swig_call_thread_plan,SWIGPythonCreateScriptedBreakpointResolver swig_bkpt_resolver_script,SWIGPythonCallBreakpointResolver swig_call_bkpt_resolver)3234435933ddSDimitry Andric void ScriptInterpreterPython::InitializeInterpreter(
3235435933ddSDimitry Andric     SWIGInitCallback swig_init_callback,
32369f2f44ceSEd Maste     SWIGBreakpointCallbackFunction swig_breakpoint_callback,
32379f2f44ceSEd Maste     SWIGWatchpointCallbackFunction swig_watchpoint_callback,
32389f2f44ceSEd Maste     SWIGPythonTypeScriptCallbackFunction swig_typescript_callback,
32399f2f44ceSEd Maste     SWIGPythonCreateSyntheticProvider swig_synthetic_script,
32409f2f44ceSEd Maste     SWIGPythonCreateCommandObject swig_create_cmd,
32419f2f44ceSEd Maste     SWIGPythonCalculateNumChildren swig_calc_children,
32429f2f44ceSEd Maste     SWIGPythonGetChildAtIndex swig_get_child_index,
32439f2f44ceSEd Maste     SWIGPythonGetIndexOfChildWithName swig_get_index_child,
32449f2f44ceSEd Maste     SWIGPythonCastPyObjectToSBValue swig_cast_to_sbvalue,
32459f2f44ceSEd Maste     SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue,
32469f2f44ceSEd Maste     SWIGPythonUpdateSynthProviderInstance swig_update_provider,
3247435933ddSDimitry Andric     SWIGPythonMightHaveChildrenSynthProviderInstance
3248435933ddSDimitry Andric         swig_mighthavechildren_provider,
32499f2f44ceSEd Maste     SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider,
32509f2f44ceSEd Maste     SWIGPythonCallCommand swig_call_command,
32519f2f44ceSEd Maste     SWIGPythonCallCommandObject swig_call_command_object,
32529f2f44ceSEd Maste     SWIGPythonCallModuleInit swig_call_module_init,
32539f2f44ceSEd Maste     SWIGPythonCreateOSPlugin swig_create_os_plugin,
3254*b5893f02SDimitry Andric     SWIGPythonCreateFrameRecognizer swig_create_frame_recognizer,
3255*b5893f02SDimitry Andric     SWIGPythonGetRecognizedArguments swig_get_recognized_arguments,
32569f2f44ceSEd Maste     SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,
32579f2f44ceSEd Maste     SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
32589f2f44ceSEd Maste     SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
32599f2f44ceSEd Maste     SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
32609f2f44ceSEd Maste     SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,
32619f2f44ceSEd Maste     SWIGPython_GetDynamicSetting swig_plugin_get,
32629f2f44ceSEd Maste     SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
3263*b5893f02SDimitry Andric     SWIGPythonCallThreadPlan swig_call_thread_plan,
3264*b5893f02SDimitry Andric     SWIGPythonCreateScriptedBreakpointResolver swig_bkpt_resolver_script,
3265*b5893f02SDimitry Andric     SWIGPythonCallBreakpointResolver swig_call_bkpt_resolver) {
32669f2f44ceSEd Maste   g_swig_init_callback = swig_init_callback;
32679f2f44ceSEd Maste   g_swig_breakpoint_callback = swig_breakpoint_callback;
32689f2f44ceSEd Maste   g_swig_watchpoint_callback = swig_watchpoint_callback;
32699f2f44ceSEd Maste   g_swig_typescript_callback = swig_typescript_callback;
32709f2f44ceSEd Maste   g_swig_synthetic_script = swig_synthetic_script;
32719f2f44ceSEd Maste   g_swig_create_cmd = swig_create_cmd;
32729f2f44ceSEd Maste   g_swig_calc_children = swig_calc_children;
32739f2f44ceSEd Maste   g_swig_get_child_index = swig_get_child_index;
32749f2f44ceSEd Maste   g_swig_get_index_child = swig_get_index_child;
32759f2f44ceSEd Maste   g_swig_cast_to_sbvalue = swig_cast_to_sbvalue;
32769f2f44ceSEd Maste   g_swig_get_valobj_sp_from_sbvalue = swig_get_valobj_sp_from_sbvalue;
32779f2f44ceSEd Maste   g_swig_update_provider = swig_update_provider;
32789f2f44ceSEd Maste   g_swig_mighthavechildren_provider = swig_mighthavechildren_provider;
32799f2f44ceSEd Maste   g_swig_getvalue_provider = swig_getvalue_provider;
32809f2f44ceSEd Maste   g_swig_call_command = swig_call_command;
32819f2f44ceSEd Maste   g_swig_call_command_object = swig_call_command_object;
32829f2f44ceSEd Maste   g_swig_call_module_init = swig_call_module_init;
32839f2f44ceSEd Maste   g_swig_create_os_plugin = swig_create_os_plugin;
3284*b5893f02SDimitry Andric   g_swig_create_frame_recognizer = swig_create_frame_recognizer;
3285*b5893f02SDimitry Andric   g_swig_get_recognized_arguments = swig_get_recognized_arguments;
32869f2f44ceSEd Maste   g_swig_run_script_keyword_process = swig_run_script_keyword_process;
32879f2f44ceSEd Maste   g_swig_run_script_keyword_thread = swig_run_script_keyword_thread;
32889f2f44ceSEd Maste   g_swig_run_script_keyword_target = swig_run_script_keyword_target;
32899f2f44ceSEd Maste   g_swig_run_script_keyword_frame = swig_run_script_keyword_frame;
32909f2f44ceSEd Maste   g_swig_run_script_keyword_value = swig_run_script_keyword_value;
32919f2f44ceSEd Maste   g_swig_plugin_get = swig_plugin_get;
32929f2f44ceSEd Maste   g_swig_thread_plan_script = swig_thread_plan_script;
32939f2f44ceSEd Maste   g_swig_call_thread_plan = swig_call_thread_plan;
3294*b5893f02SDimitry Andric   g_swig_bkpt_resolver_script = swig_bkpt_resolver_script;
3295*b5893f02SDimitry Andric   g_swig_call_bkpt_resolver = swig_call_bkpt_resolver;
32969f2f44ceSEd Maste }
32979f2f44ceSEd Maste 
InitializePrivate()3298435933ddSDimitry Andric void ScriptInterpreterPython::InitializePrivate() {
32994bb0738eSEd Maste   if (g_initialized)
33004bb0738eSEd Maste     return;
33014bb0738eSEd Maste 
33029f2f44ceSEd Maste   g_initialized = true;
33039f2f44ceSEd Maste 
33045517e702SDimitry Andric   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
33055517e702SDimitry Andric   Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
33069f2f44ceSEd Maste 
3307435933ddSDimitry Andric   // RAII-based initialization which correctly handles multiple-initialization,
33084ba319b5SDimitry Andric   // version- specific differences among Python 2 and Python 3, and saving and
33094ba319b5SDimitry Andric   // restoring various other pieces of state that can get mucked with during
33104ba319b5SDimitry Andric   // initialization.
33119f2f44ceSEd Maste   InitializePythonRAII initialize_guard;
33129f2f44ceSEd Maste 
33139f2f44ceSEd Maste   if (g_swig_init_callback)
33149f2f44ceSEd Maste     g_swig_init_callback();
33159f2f44ceSEd Maste 
3316435933ddSDimitry Andric   // Update the path python uses to search for modules to include the current
3317435933ddSDimitry Andric   // directory.
33189f2f44ceSEd Maste 
33199f2f44ceSEd Maste   PyRun_SimpleString("import sys");
33209f2f44ceSEd Maste   AddToSysPath(AddLocation::End, ".");
33219f2f44ceSEd Maste 
3322435933ddSDimitry Andric   // Don't denormalize paths when calling file_spec.GetPath().  On platforms
33234ba319b5SDimitry Andric   // that use a backslash as the path separator, this will result in executing
33244ba319b5SDimitry Andric   // python code containing paths with unescaped backslashes.  But Python also
33254ba319b5SDimitry Andric   // accepts forward slashes, so to make life easier we just use that.
33264ba319b5SDimitry Andric   if (FileSpec file_spec = GetPythonDir())
33279f2f44ceSEd Maste     AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));
33284ba319b5SDimitry Andric   if (FileSpec file_spec = HostInfo::GetShlibDir())
33299f2f44ceSEd Maste     AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));
33309f2f44ceSEd Maste 
3331435933ddSDimitry Andric   PyRun_SimpleString("sys.dont_write_bytecode = 1; import "
3332435933ddSDimitry Andric                      "lldb.embedded_interpreter; from "
3333435933ddSDimitry Andric                      "lldb.embedded_interpreter import run_python_interpreter; "
3334435933ddSDimitry Andric                      "from lldb.embedded_interpreter import run_one_line");
33359f2f44ceSEd Maste }
33369f2f44ceSEd Maste 
AddToSysPath(AddLocation location,std::string path)3337435933ddSDimitry Andric void ScriptInterpreterPython::AddToSysPath(AddLocation location,
3338435933ddSDimitry Andric                                            std::string path) {
33399f2f44ceSEd Maste   std::string path_copy;
33409f2f44ceSEd Maste 
33419f2f44ceSEd Maste   std::string statement;
3342435933ddSDimitry Andric   if (location == AddLocation::Beginning) {
33439f2f44ceSEd Maste     statement.assign("sys.path.insert(0,\"");
33449f2f44ceSEd Maste     statement.append(path);
33459f2f44ceSEd Maste     statement.append("\")");
3346435933ddSDimitry Andric   } else {
33479f2f44ceSEd Maste     statement.assign("sys.path.append(\"");
33489f2f44ceSEd Maste     statement.append(path);
33499f2f44ceSEd Maste     statement.append("\")");
33509f2f44ceSEd Maste   }
33519f2f44ceSEd Maste   PyRun_SimpleString(statement.c_str());
33529f2f44ceSEd Maste }
33539f2f44ceSEd Maste 
33544ba319b5SDimitry Andric // We are intentionally NOT calling Py_Finalize here (this would be the logical
33554ba319b5SDimitry Andric // place to call it).  Calling Py_Finalize here causes test suite runs to seg
33564ba319b5SDimitry Andric // fault:  The test suite runs in Python.  It registers SBDebugger::Terminate to
33574ba319b5SDimitry Andric // be called 'at_exit'.  When the test suite Python harness finishes up, it
33584ba319b5SDimitry Andric // calls Py_Finalize, which calls all the 'at_exit' registered functions.
33594ba319b5SDimitry Andric // SBDebugger::Terminate calls Debugger::Terminate, which calls lldb::Terminate,
33604ba319b5SDimitry Andric // which calls ScriptInterpreter::Terminate, which calls
33614ba319b5SDimitry Andric // ScriptInterpreterPython::Terminate.  So if we call Py_Finalize here, we end
33624ba319b5SDimitry Andric // up with Py_Finalize being called from within Py_Finalize, which results in a
33634ba319b5SDimitry Andric // seg fault. Since this function only gets called when lldb is shutting down
33644ba319b5SDimitry Andric // and going away anyway, the fact that we don't actually call Py_Finalize
33654ba319b5SDimitry Andric // should not cause any problems (everything should shut down/go away anyway
33664ba319b5SDimitry Andric // when the process exits).
33674ba319b5SDimitry Andric //
33684ba319b5SDimitry Andric // void ScriptInterpreterPython::Terminate() { Py_Finalize (); }
33699f2f44ceSEd Maste 
33704ba319b5SDimitry Andric #endif // LLDB_DISABLE_PYTHON
3371