ScriptInterpreterPython.h revision f3ec4617297810223deb545cb68214ca4dd8009c
1//===-- ScriptInterpreterPython.h -------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10
11#ifndef liblldb_ScriptInterpreterPython_h_
12#define liblldb_ScriptInterpreterPython_h_
13
14#ifdef LLDB_DISABLE_PYTHON
15
16// Python is disabled in this build
17
18#else
19
20#if defined (__APPLE__)
21#include <Python/Python.h>
22#else
23#include <Python.h>
24#endif
25
26#include "lldb/lldb-private.h"
27#include "lldb/Interpreter/ScriptInterpreter.h"
28#include "lldb/Core/InputReader.h"
29#include "lldb/Host/Terminal.h"
30
31namespace lldb_private {
32
33class ScriptInterpreterPython : public ScriptInterpreter
34{
35public:
36
37    ScriptInterpreterPython (CommandInterpreter &interpreter);
38
39    ~ScriptInterpreterPython ();
40
41    bool
42    ExecuteOneLine (const char *command, CommandReturnObject *result, bool enable_io);
43
44    void
45    ExecuteInterpreterLoop ();
46
47    bool
48    ExecuteOneLineWithReturn (const char *in_string,
49                              ScriptInterpreter::ScriptReturnType return_type,
50                              void *ret_value,
51                              bool enable_io);
52
53    bool
54    ExecuteMultipleLines (const char *in_string, bool enable_io);
55
56    bool
57    ExportFunctionDefinitionToInterpreter (StringList &function_def);
58
59    bool
60    GenerateTypeScriptFunction (StringList &input, std::string& output, void* name_token = NULL);
61
62    bool
63    GenerateTypeSynthClass (StringList &input, std::string& output, void* name_token = NULL);
64
65    bool
66    GenerateTypeSynthClass (const char* oneliner, std::string& output, void* name_token = NULL);
67
68    // use this if the function code is just a one-liner script
69    bool
70    GenerateTypeScriptFunction (const char* oneliner, std::string& output, void* name_token = NULL);
71
72    virtual bool
73    GenerateScriptAliasFunction (StringList &input, std::string& output);
74
75    lldb::ScriptInterpreterObjectSP
76    CreateSyntheticScriptedProvider (std::string class_name,
77                                     lldb::ValueObjectSP valobj);
78
79    virtual uint32_t
80    CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor);
81
82    virtual lldb::ValueObjectSP
83    GetChildAtIndex (const lldb::ScriptInterpreterObjectSP& implementor, uint32_t idx);
84
85    virtual int
86    GetIndexOfChildWithName (const lldb::ScriptInterpreterObjectSP& implementor, const char* child_name);
87
88    virtual bool
89    UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor);
90
91    virtual bool
92    RunScriptBasedCommand(const char* impl_function,
93                          const char* args,
94                          ScriptedCommandSynchronicity synchronicity,
95                          lldb_private::CommandReturnObject& cmd_retobj,
96                          Error& error);
97
98    bool
99    GenerateFunction(const char *signature, const StringList &input);
100
101    bool
102    GenerateBreakpointCommandCallbackData (StringList &input, std::string& output);
103
104    bool
105    GenerateWatchpointCommandCallbackData (StringList &input, std::string& output);
106
107    static size_t
108    GenerateBreakpointOptionsCommandCallback (void *baton,
109                                              InputReader &reader,
110                                              lldb::InputReaderAction notification,
111                                              const char *bytes,
112                                              size_t bytes_len);
113
114    static size_t
115    GenerateWatchpointOptionsCommandCallback (void *baton,
116                                              InputReader &reader,
117                                              lldb::InputReaderAction notification,
118                                              const char *bytes,
119                                              size_t bytes_len);
120
121    static bool
122    BreakpointCallbackFunction (void *baton,
123                                StoppointCallbackContext *context,
124                                lldb::user_id_t break_id,
125                                lldb::user_id_t break_loc_id);
126
127    static bool
128    WatchpointCallbackFunction (void *baton,
129                                StoppointCallbackContext *context,
130                                lldb::user_id_t watch_id);
131
132    virtual bool
133    GetScriptedSummary (const char *function_name,
134                        lldb::ValueObjectSP valobj,
135                        lldb::ScriptInterpreterObjectSP& callee_wrapper_sp,
136                        std::string& retval);
137
138    virtual std::string
139    GetDocumentationForItem (const char* item);
140
141    virtual bool
142    LoadScriptingModule (const char* filename,
143                         bool can_reload,
144                         lldb_private::Error& error);
145
146    virtual lldb::ScriptInterpreterObjectSP
147    MakeScriptObject (void* object);
148
149    void
150    CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options,
151                                             CommandReturnObject &result);
152
153    void
154    CollectDataForWatchpointCommandCallback (WatchpointOptions *wp_options,
155                                             CommandReturnObject &result);
156
157    /// Set a Python one-liner as the callback for the breakpoint.
158    void
159    SetBreakpointCommandCallback (BreakpointOptions *bp_options,
160                                  const char *oneliner);
161
162    /// Set a one-liner as the callback for the watchpoint.
163    void
164    SetWatchpointCommandCallback (WatchpointOptions *wp_options,
165                                  const char *oneliner);
166
167    StringList
168    ReadCommandInputFromUser (FILE *in_file);
169
170    virtual void
171    ResetOutputFileHandle (FILE *new_fh);
172
173    static lldb::thread_result_t
174    RunEmbeddedPythonInterpreter (lldb::thread_arg_t baton);
175
176    static void
177    InitializePrivate ();
178
179    static void
180    InitializeInterpreter (SWIGInitCallback python_swig_init_callback);
181
182protected:
183
184    void
185    EnterSession ();
186
187    void
188    LeaveSession ();
189
190    void
191    SaveTerminalState (int fd);
192
193    void
194    RestoreTerminalState ();
195
196private:
197
198    class SynchronicityHandler
199    {
200    private:
201        lldb::DebuggerSP             m_debugger_sp;
202        ScriptedCommandSynchronicity m_synch_wanted;
203        bool                         m_old_asynch;
204    public:
205        SynchronicityHandler(lldb::DebuggerSP,
206                             ScriptedCommandSynchronicity);
207        ~SynchronicityHandler();
208    };
209
210    class ScriptInterpreterPythonObject : public ScriptInterpreterObject
211    {
212    public:
213        ScriptInterpreterPythonObject() :
214        ScriptInterpreterObject()
215        {}
216
217        ScriptInterpreterPythonObject(void* obj) :
218        ScriptInterpreterObject(obj)
219        {
220            Py_XINCREF(m_object);
221        }
222
223        virtual
224        ~ScriptInterpreterPythonObject()
225        {
226            Py_XDECREF(m_object);
227            m_object = NULL;
228        }
229        private:
230            DISALLOW_COPY_AND_ASSIGN (ScriptInterpreterPythonObject);
231    };
232
233	class Locker
234	{
235	public:
236
237        enum OnEntry
238        {
239            AcquireLock         = 0x0001,
240            InitSession         = 0x0002
241        };
242
243        enum OnLeave
244        {
245            FreeLock            = 0x0001,
246            FreeAcquiredLock    = 0x0002,    // do not free the lock if we already held it when calling constructor
247            TearDownSession     = 0x0004
248        };
249
250        Locker (ScriptInterpreterPython *py_interpreter = NULL,
251                uint16_t on_entry = AcquireLock | InitSession,
252                uint16_t on_leave = FreeLock | TearDownSession,
253                FILE* wait_msg_handle = NULL);
254
255    	~Locker ();
256
257        static bool
258        CurrentThreadHasPythonLock ();
259
260	private:
261
262        bool
263        DoAcquireLock ();
264
265        bool
266        DoInitSession ();
267
268        bool
269        DoFreeLock ();
270
271        bool
272        DoTearDownSession ();
273
274        static bool
275        TryGetPythonLock (uint32_t seconds_to_wait);
276
277        static void
278        ReleasePythonLock ();
279
280    	bool                     m_need_session;
281    	bool                     m_release_lock;
282    	ScriptInterpreterPython *m_python_interpreter;
283    	FILE*                    m_tmp_fh;
284	};
285
286    class PythonInputReaderManager
287    {
288    public:
289        PythonInputReaderManager (ScriptInterpreterPython *interpreter);
290
291        operator bool()
292        {
293            return m_error;
294        }
295
296        ~PythonInputReaderManager();
297
298    private:
299
300        static size_t
301        InputReaderCallback (void *baton,
302                                           InputReader &reader,
303                                           lldb::InputReaderAction notification,
304                                           const char *bytes,
305                                           size_t bytes_len);
306
307        static lldb::thread_result_t
308        RunPythonInputReader (lldb::thread_arg_t baton);
309
310        ScriptInterpreterPython *m_interpreter;
311        lldb::DebuggerSP m_debugger_sp;
312        lldb::InputReaderSP m_reader_sp;
313        bool m_error;
314    };
315
316    static size_t
317    InputReaderCallback (void *baton,
318                         InputReader &reader,
319                         lldb::InputReaderAction notification,
320                         const char *bytes,
321                         size_t bytes_len);
322
323
324    lldb_utility::PseudoTerminal m_embedded_python_pty;
325    lldb::InputReaderSP m_embedded_thread_input_reader_sp;
326    FILE *m_dbg_stdout;
327    PyObject *m_new_sysout;
328    PyObject *m_old_sysout;
329    PyObject *m_old_syserr;
330    PyObject *m_run_one_line;
331    std::string m_dictionary_name;
332    TerminalState m_terminal_state;
333    bool m_session_is_active;
334    bool m_pty_slave_is_open;
335    bool m_valid_session;
336
337};
338} // namespace lldb_private
339
340#endif // #ifdef LLDB_DISABLE_PYTHON
341
342#endif // #ifndef liblldb_ScriptInterpreterPython_h_
343