ScriptInterpreterPython.h revision a1ba314f3c8eb40424547836769e93f9b65e7969
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    static size_t
105    GenerateBreakpointOptionsCommandCallback (void *baton,
106                                              InputReader &reader,
107                                              lldb::InputReaderAction notification,
108                                              const char *bytes,
109                                              size_t bytes_len);
110
111    static bool
112    BreakpointCallbackFunction (void *baton,
113                                StoppointCallbackContext *context,
114                                lldb::user_id_t break_id,
115                                lldb::user_id_t break_loc_id);
116
117    virtual bool
118    GetScriptedSummary (const char *function_name,
119                        lldb::ValueObjectSP valobj,
120                        lldb::ScriptInterpreterObjectSP& callee_wrapper_sp,
121                        std::string& retval);
122
123    virtual std::string
124    GetDocumentationForItem (const char* item);
125
126    virtual bool
127    LoadScriptingModule (const char* filename,
128                         bool can_reload,
129                         lldb_private::Error& error);
130
131    virtual lldb::ScriptInterpreterObjectSP
132    MakeScriptObject (void* object);
133
134    void
135    CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options,
136                                             CommandReturnObject &result);
137
138    /// Set a Python one-liner as the callback for the breakpoint.
139    void
140    SetBreakpointCommandCallback (BreakpointOptions *bp_options,
141                                  const char *oneliner);
142
143    StringList
144    ReadCommandInputFromUser (FILE *in_file);
145
146    virtual void
147    ResetOutputFileHandle (FILE *new_fh);
148
149    static lldb::thread_result_t
150    RunEmbeddedPythonInterpreter (lldb::thread_arg_t baton);
151
152    static void
153    InitializePrivate ();
154
155    static void
156    InitializeInterpreter (SWIGInitCallback python_swig_init_callback);
157
158protected:
159
160    void
161    EnterSession ();
162
163    void
164    LeaveSession ();
165
166    void
167    SaveTerminalState (int fd);
168
169    void
170    RestoreTerminalState ();
171
172private:
173
174    class SynchronicityHandler
175    {
176    private:
177        lldb::DebuggerSP             m_debugger_sp;
178        ScriptedCommandSynchronicity m_synch_wanted;
179        bool                         m_old_asynch;
180    public:
181        SynchronicityHandler(lldb::DebuggerSP,
182                             ScriptedCommandSynchronicity);
183        ~SynchronicityHandler();
184    };
185
186    class ScriptInterpreterPythonObject : public ScriptInterpreterObject
187    {
188    public:
189        ScriptInterpreterPythonObject() :
190        ScriptInterpreterObject()
191        {}
192
193        ScriptInterpreterPythonObject(void* obj) :
194        ScriptInterpreterObject(obj)
195        {
196            Py_XINCREF(m_object);
197        }
198
199        virtual
200        ~ScriptInterpreterPythonObject()
201        {
202            Py_XDECREF(m_object);
203            m_object = NULL;
204        }
205        private:
206            DISALLOW_COPY_AND_ASSIGN (ScriptInterpreterPythonObject);
207    };
208
209	class Locker
210	{
211	public:
212
213        enum OnEntry
214        {
215            AcquireLock         = 0x0001,
216            InitSession         = 0x0002
217        };
218
219        enum OnLeave
220        {
221            FreeLock            = 0x0001,
222            FreeAcquiredLock    = 0x0002,    // do not free the lock if we already held it when calling constructor
223            TearDownSession     = 0x0004
224        };
225
226        Locker (ScriptInterpreterPython *py_interpreter = NULL,
227                uint16_t on_entry = AcquireLock | InitSession,
228                uint16_t on_leave = FreeLock | TearDownSession,
229                FILE* wait_msg_handle = NULL);
230
231    	~Locker ();
232
233        static bool
234        CurrentThreadHasPythonLock ();
235
236	private:
237
238        bool
239        DoAcquireLock ();
240
241        bool
242        DoInitSession ();
243
244        bool
245        DoFreeLock ();
246
247        bool
248        DoTearDownSession ();
249
250        static bool
251        TryGetPythonLock (uint32_t seconds_to_wait);
252
253        static void
254        ReleasePythonLock ();
255
256    	bool                     m_need_session;
257    	bool                     m_release_lock;
258    	ScriptInterpreterPython *m_python_interpreter;
259    	FILE*                    m_tmp_fh;
260	};
261
262    class PythonInputReaderManager
263    {
264    public:
265        PythonInputReaderManager (ScriptInterpreterPython *interpreter);
266
267        operator bool()
268        {
269            return m_error;
270        }
271
272        ~PythonInputReaderManager();
273
274    private:
275
276        static size_t
277        InputReaderCallback (void *baton,
278                                           InputReader &reader,
279                                           lldb::InputReaderAction notification,
280                                           const char *bytes,
281                                           size_t bytes_len);
282
283        static lldb::thread_result_t
284        RunPythonInputReader (lldb::thread_arg_t baton);
285
286        ScriptInterpreterPython *m_interpreter;
287        lldb::DebuggerSP m_debugger_sp;
288        lldb::InputReaderSP m_reader_sp;
289        bool m_error;
290    };
291
292    static size_t
293    InputReaderCallback (void *baton,
294                         InputReader &reader,
295                         lldb::InputReaderAction notification,
296                         const char *bytes,
297                         size_t bytes_len);
298
299
300    lldb_utility::PseudoTerminal m_embedded_python_pty;
301    lldb::InputReaderSP m_embedded_thread_input_reader_sp;
302    FILE *m_dbg_stdout;
303    PyObject *m_new_sysout;
304    PyObject *m_old_sysout;
305    PyObject *m_old_syserr;
306    PyObject *m_run_one_line;
307    std::string m_dictionary_name;
308    TerminalState m_terminal_state;
309    bool m_session_is_active;
310    bool m_pty_slave_is_open;
311    bool m_valid_session;
312
313};
314} // namespace lldb_private
315
316#endif // #ifdef LLDB_DISABLE_PYTHON
317
318#endif // #ifndef liblldb_ScriptInterpreterPython_h_
319