[Lldb-commits] [lldb] r232136 - Bulk of the infrastructure work to allow script commands to be backed by object instances in addition to free functions

Enrico Granata egranata at apple.com
Thu Mar 12 19:20:41 PDT 2015


Author: enrico
Date: Thu Mar 12 21:20:41 2015
New Revision: 232136

URL: http://llvm.org/viewvc/llvm-project?rev=232136&view=rev
Log:
Bulk of the infrastructure work to allow script commands to be backed by object instances in addition to free functions
This works by creating a command backed by a class whose interface should - at least - include

def __init__(self, debugger, session_dict)
def __call__(self, args, return_obj, exe_ctx)

What works:
- adding a command via command script add --class
- calling a thusly created command

What is missing:
- support for custom help
- test cases

The missing parts will follow over the next couple of days

This is an improvement over the existing system as:
a) it provides an obvious location for commands to provide help strings (i.e. methods)
b) it allows commands to store state in an obvious fashion
c) it allows us to easily add features to script commands over time (option parsing and subcommands registration, I am looking at you :-)


Modified:
    lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
    lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
    lldb/trunk/scripts/Python/python-wrapper.swig
    lldb/trunk/source/API/SBCommandInterpreter.cpp
    lldb/trunk/source/Commands/CommandObjectCommands.cpp
    lldb/trunk/source/Interpreter/ScriptInterpreter.cpp
    lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp

Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h?rev=232136&r1=232135&r2=232136&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h Thu Mar 12 21:20:41 2015
@@ -105,6 +105,10 @@ public:
                                                         const char *session_dictionary_name,
                                                         const lldb::ValueObjectSP& valobj_sp);
 
+    typedef void* (*SWIGPythonCreateCommandObject) (const char *python_class_name,
+                                                    const char *session_dictionary_name,
+                                                    const lldb::DebuggerSP debugger_sp);
+    
     typedef void* (*SWIGPythonCreateScriptedThreadPlan) (const char *python_class_name,
                                                         const char *session_dictionary_name,
                                                         const lldb::ThreadPlanSP& thread_plan_sp);
@@ -130,6 +134,13 @@ public:
                                                                  const char* args,
                                                                  lldb_private::CommandReturnObject& cmd_retobj,
                                                                  lldb::ExecutionContextRefSP exe_ctx_ref_sp);
+
+    typedef bool            (*SWIGPythonCallCommandObject)        (void *implementor,
+                                                                   lldb::DebuggerSP& debugger,
+                                                                   const char* args,
+                                                                   lldb_private::CommandReturnObject& cmd_retobj,
+                                                                   lldb::ExecutionContextRefSP exe_ctx_ref_sp);
+
     
     typedef bool            (*SWIGPythonCallModuleInit)         (const char *python_module_name,
                                                                  const char *session_dictionary_name,
@@ -331,6 +342,12 @@ public:
     {
         return lldb::ScriptInterpreterObjectSP();
     }
+
+    virtual lldb::ScriptInterpreterObjectSP
+    CreateScriptCommandObject (const char *class_name)
+    {
+        return lldb::ScriptInterpreterObjectSP();
+    }
     
     virtual lldb::ScriptInterpreterObjectSP
     OSPlugin_CreatePluginObject (const char *class_name,
@@ -529,6 +546,17 @@ public:
     }
     
     virtual bool
+    RunScriptBasedCommand (lldb::ScriptInterpreterObjectSP impl_obj_sp,
+                           const char* args,
+                           ScriptedCommandSynchronicity synchronicity,
+                           lldb_private::CommandReturnObject& cmd_retobj,
+                           Error& error,
+                           const lldb_private::ExecutionContext& exe_ctx)
+    {
+        return false;
+    }
+    
+    virtual bool
     RunScriptFormatKeyword (const char* impl_function,
                             Process* process,
                             std::string& output,
@@ -635,6 +663,7 @@ public:
                            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,
@@ -644,6 +673,7 @@ public:
                            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,
                            SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,

Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h?rev=232136&r1=232135&r2=232136&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h Thu Mar 12 21:20:41 2015
@@ -85,6 +85,9 @@ public:
                                      lldb::ValueObjectSP valobj) override;
 
     lldb::ScriptInterpreterObjectSP
+    CreateScriptCommandObject (const char *class_name) override;
+    
+    lldb::ScriptInterpreterObjectSP
     CreateScriptedThreadPlan (const char *class_name,
                               lldb::ThreadPlanSP thread_plan) override;
 
@@ -155,6 +158,14 @@ public:
                           Error& error,
                           const lldb_private::ExecutionContext& exe_ctx) override;
     
+    bool
+    RunScriptBasedCommand (lldb::ScriptInterpreterObjectSP impl_obj_sp,
+                           const char* args,
+                           ScriptedCommandSynchronicity synchronicity,
+                           lldb_private::CommandReturnObject& cmd_retobj,
+                           Error& error,
+                           const lldb_private::ExecutionContext& exe_ctx) override;
+    
     Error
     GenerateFunction(const char *signature, const StringList &input) override;
     
@@ -294,6 +305,7 @@ public:
                            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,
@@ -303,6 +315,7 @@ public:
                            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,
                            SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,

Modified: lldb/trunk/scripts/Python/python-wrapper.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-wrapper.swig?rev=232136&r1=232135&r2=232136&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/python-wrapper.swig (original)
+++ lldb/trunk/scripts/Python/python-wrapper.swig Thu Mar 12 21:20:41 2015
@@ -453,6 +453,44 @@ LLDBSwigPythonCreateSyntheticProvider
 }
 
 SWIGEXPORT void*
+LLDBSwigPythonCreateCommandObject
+(
+    const char *python_class_name,
+    const char *session_dictionary_name,
+    const lldb::DebuggerSP debugger_sp
+)
+{
+    PyObject* retval = NULL;
+
+    if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
+        Py_RETURN_NONE;
+
+    lldb::SBDebugger debugger_sb(debugger_sp);
+
+    {
+        PyErr_Cleaner py_err_cleaner(true);
+        
+        PyCallable pfunc = PyCallable::FindWithFunctionName(python_class_name,session_dictionary_name);
+        
+        if (!pfunc)
+            return retval;
+        
+        PyObject* session_dict = NULL;
+        session_dict = FindSessionDictionary(session_dictionary_name);
+        retval = pfunc(debugger_sb, session_dict);
+        
+        Py_XINCREF (session_dict);
+        
+        Py_XINCREF(retval);
+    }
+    
+    if (retval)
+        return retval;
+    else
+        Py_RETURN_NONE;
+}
+
+SWIGEXPORT void*
 LLDBSwigPythonCreateScriptedThreadPlan
 (
     const char *python_class_name,
@@ -840,6 +878,46 @@ LLDBSwigPythonCallCommand
         Py_XDECREF (pvalue);
         
         retval = true;
+    }
+    
+    return retval;
+}
+
+SWIGEXPORT bool
+LLDBSwigPythonCallCommandObject
+(
+    PyObject *implementor,
+    lldb::DebuggerSP& debugger,
+    const char* args,
+    lldb_private::CommandReturnObject& cmd_retobj,
+    lldb::ExecutionContextRefSP exe_ctx_ref_sp
+)
+{
+
+    lldb::SBCommandReturnObject cmd_retobj_sb(&cmd_retobj);
+    SBCommandReturnObjectReleaser cmd_retobj_sb_releaser(cmd_retobj_sb);
+    lldb::SBDebugger debugger_sb(debugger);
+    lldb::SBExecutionContext exe_ctx_sb(exe_ctx_ref_sp);
+
+    bool retval = false;
+
+    {
+        PyErr_Cleaner py_err_cleaner(true);
+
+        PyCallable pfunc = PyCallable::FindWithMemberFunction(implementor,"__call__");
+    
+        if (!pfunc)
+            return NULL;
+
+        // pass the pointer-to cmd_retobj_sb or watch the underlying object disappear from under you
+        // see comment above for SBCommandReturnObjectReleaser for further details
+        PyObject* pvalue = NULL;
+
+        pvalue = pfunc(debugger_sb, args, exe_ctx_sb, &cmd_retobj_sb);
+
+        Py_XDECREF (pvalue);
+        
+        retval = true;
     }
     
     return retval;

Modified: lldb/trunk/source/API/SBCommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBCommandInterpreter.cpp?rev=232136&r1=232135&r2=232136&view=diff
==============================================================================
--- lldb/trunk/source/API/SBCommandInterpreter.cpp (original)
+++ lldb/trunk/source/API/SBCommandInterpreter.cpp Thu Mar 12 21:20:41 2015
@@ -603,6 +603,10 @@ LLDBSwigPythonCreateSyntheticProvider (c
                                        const char *session_dictionary_name,
                                        const lldb::ValueObjectSP& valobj_sp);
 
+extern "C" void*
+LLDBSwigPythonCreateCommandObject (const char *python_class_name,
+                                   const char *session_dictionary_name,
+                                   const lldb::DebuggerSP debugger_sp);
 
 extern "C" void*
 LLDBSwigPythonCreateScriptedThreadPlan (const char *python_class_name,
@@ -648,6 +652,13 @@ LLDBSwigPythonCallCommand (const char *p
                            lldb::ExecutionContextRefSP exe_ctx_ref_sp);
 
 extern "C" bool
+LLDBSwigPythonCallCommandObject (void *implementor,
+                                 lldb::DebuggerSP& debugger,
+                                 const char* args,
+                                 lldb_private::CommandReturnObject& cmd_retobj,
+                                 lldb::ExecutionContextRefSP exe_ctx_ref_sp);
+
+extern "C" bool
 LLDBSwigPythonCallModuleInit (const char *python_module_name,
                               const char *session_dictionary_name,
                               lldb::DebuggerSP& debugger);
@@ -708,6 +719,7 @@ SBCommandInterpreter::InitializeSWIG ()
                                                   LLDBSwigPythonWatchpointCallbackFunction,
                                                   LLDBSwigPythonCallTypeScript,
                                                   LLDBSwigPythonCreateSyntheticProvider,
+                                                  LLDBSwigPythonCreateCommandObject,
                                                   LLDBSwigPython_CalculateNumChildren,
                                                   LLDBSwigPython_GetChildAtIndex,
                                                   LLDBSwigPython_GetIndexOfChildWithName,
@@ -717,6 +729,7 @@ SBCommandInterpreter::InitializeSWIG ()
                                                   LLDBSwigPython_MightHaveChildrenSynthProviderInstance,
                                                   LLDBSwigPython_GetValueSynthProviderInstance,
                                                   LLDBSwigPythonCallCommand,
+                                                  LLDBSwigPythonCallCommandObject,
                                                   LLDBSwigPythonCallModuleInit,
                                                   LLDBSWIGPythonCreateOSPlugin,
                                                   LLDBSWIGPythonRunScriptKeywordProcess,

Modified: lldb/trunk/source/Commands/CommandObjectCommands.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectCommands.cpp?rev=232136&r1=232135&r2=232136&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectCommands.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectCommands.cpp Thu Mar 12 21:20:41 2015
@@ -1430,6 +1430,96 @@ protected:
     
 };
 
+class CommandObjectScriptingObject : public CommandObjectRaw
+{
+private:
+    lldb::ScriptInterpreterObjectSP m_cmd_obj_sp;
+    ScriptedCommandSynchronicity m_synchro;
+    
+public:
+    
+    CommandObjectScriptingObject (CommandInterpreter &interpreter,
+                                  std::string name,
+                                  lldb::ScriptInterpreterObjectSP cmd_obj_sp,
+                                  ScriptedCommandSynchronicity synch) :
+    CommandObjectRaw (interpreter,
+                      name.c_str(),
+                      NULL,
+                      NULL),
+    m_cmd_obj_sp(cmd_obj_sp),
+    m_synchro(synch)
+    {
+        StreamString stream;
+        stream.Printf("For more information run 'help %s'",name.c_str());
+        SetHelp(stream.GetData());
+    }
+    
+    virtual
+    ~CommandObjectScriptingObject ()
+    {
+    }
+    
+    virtual bool
+    IsRemovable () const
+    {
+        return true;
+    }
+    
+    lldb::ScriptInterpreterObjectSP
+    GetImplementingObject ()
+    {
+        return m_cmd_obj_sp;
+    }
+    
+    ScriptedCommandSynchronicity
+    GetSynchronicity ()
+    {
+        return m_synchro;
+    }
+    
+    virtual const char *
+    GetHelpLong ()
+    {
+        return CommandObjectRaw::GetHelpLong();
+    }
+    
+protected:
+    virtual bool
+    DoExecute (const char *raw_command_line, CommandReturnObject &result)
+    {
+        ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
+        
+        Error error;
+        
+        result.SetStatus(eReturnStatusInvalid);
+        
+        if (!scripter || scripter->RunScriptBasedCommand(m_cmd_obj_sp,
+                                                         raw_command_line,
+                                                         m_synchro,
+                                                         result,
+                                                         error,
+                                                         m_exe_ctx) == false)
+        {
+            result.AppendError(error.AsCString());
+            result.SetStatus(eReturnStatusFailed);
+        }
+        else
+        {
+            // Don't change the status if the command already set it...
+            if (result.GetStatus() == eReturnStatusInvalid)
+            {
+                if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
+                    result.SetStatus(eReturnStatusSuccessFinishNoResult);
+                else
+                    result.SetStatus(eReturnStatusSuccessFinishResult);
+            }
+        }
+        
+        return result.Succeeded();
+    }
+    
+};
+
 //-------------------------------------------------------------------------
 // CommandObjectCommandsScriptImport
 //-------------------------------------------------------------------------
@@ -1652,7 +1742,11 @@ protected:
     public:
         
         CommandOptions (CommandInterpreter &interpreter) :
-            Options (interpreter)
+            Options (interpreter),
+            m_class_name(),
+            m_funct_name(),
+            m_short_help(),
+            m_synchronicity(eScriptedCommandSynchronicitySynchronous)
         {
         }
         
@@ -1671,6 +1765,10 @@ protected:
                     if (option_arg)
                         m_funct_name.assign(option_arg);
                     break;
+                case 'c':
+                    if (option_arg)
+                        m_class_name.assign(option_arg);
+                    break;
                 case 'h':
                     if (option_arg)
                         m_short_help.assign(option_arg);
@@ -1691,6 +1789,7 @@ protected:
         void
         OptionParsingStarting ()
         {
+            m_class_name.clear();
             m_funct_name.clear();
             m_short_help.clear();
             m_synchronicity = eScriptedCommandSynchronicitySynchronous;
@@ -1708,6 +1807,7 @@ protected:
         
         // Instance variables to hold the values for command options.
         
+        std::string m_class_name;
         std::string m_funct_name;
         std::string m_short_help;
         ScriptedCommandSynchronicity m_synchronicity;
@@ -1812,20 +1912,55 @@ protected:
         m_short_help.assign(m_options.m_short_help);
         m_synchronicity = m_options.m_synchronicity;
         
-        if (m_options.m_funct_name.empty())
+        if (m_options.m_class_name.empty())
         {
-            m_interpreter.GetPythonCommandsFromIOHandler ("     ",  // Prompt
-                                                          *this,    // IOHandlerDelegate
-                                                          true,     // Run IOHandler in async mode
-                                                          NULL);    // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
+            if (m_options.m_funct_name.empty())
+            {
+                m_interpreter.GetPythonCommandsFromIOHandler ("     ",  // Prompt
+                                                              *this,    // IOHandlerDelegate
+                                                              true,     // Run IOHandler in async mode
+                                                              NULL);    // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
+            }
+            else
+            {
+                CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
+                                                                        m_cmd_name,
+                                                                        m_options.m_funct_name,
+                                                                        m_options.m_short_help,
+                                                                        m_synchronicity));
+                if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
+                {
+                    result.SetStatus (eReturnStatusSuccessFinishNoResult);
+                }
+                else
+                {
+                    result.AppendError("cannot add command");
+                    result.SetStatus (eReturnStatusFailed);
+                }
+            }
         }
         else
         {
-            CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
-                                                                    m_cmd_name,
-                                                                    m_options.m_funct_name,
-                                                                    m_options.m_short_help,
-                                                                    m_synchronicity));
+            ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter();
+            if (!interpreter)
+            {
+                result.AppendError("cannot find ScriptInterpreter");
+                result.SetStatus(eReturnStatusFailed);
+                return false;
+            }
+            
+            auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str());
+            if (!cmd_obj_sp)
+            {
+                result.AppendError("cannot create helper object");
+                result.SetStatus(eReturnStatusFailed);
+                return false;
+            }
+            
+            CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter,
+                                                                     m_cmd_name,
+                                                                     cmd_obj_sp,
+                                                                     m_synchronicity));
             if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
             {
                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
@@ -1859,8 +1994,9 @@ OptionDefinition
 CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
 {
     { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction,        "Name of the Python function to bind to this command name."},
-    { LLDB_OPT_SET_1, false, "help"  , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeHelpText, "The help text to display for this command."},
-    { LLDB_OPT_SET_1, false, "synchronicity", 's', OptionParser::eRequiredArgument, NULL, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity,        "Set the synchronicity of this command's executions with regard to LLDB event system."},
+    { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass,        "Name of the Python class to bind to this command name."},
+    { LLDB_OPT_SET_ALL, false, "help"  , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeHelpText, "The help text to display for this command."},
+    { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, NULL, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity,        "Set the synchronicity of this command's executions with regard to LLDB event system."},
     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
 };
 

Modified: lldb/trunk/source/Interpreter/ScriptInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreter.cpp?rev=232136&r1=232135&r2=232136&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreter.cpp Thu Mar 12 21:20:41 2015
@@ -117,6 +117,7 @@ ScriptInterpreter::InitializeInterpreter
                                           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,
@@ -126,6 +127,7 @@ ScriptInterpreter::InitializeInterpreter
                                           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,
                                           SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,
@@ -143,6 +145,7 @@ ScriptInterpreter::InitializeInterpreter
                                                     swig_watchpoint_callback,
                                                     swig_typescript_callback,
                                                     swig_synthetic_script,
+                                                    swig_create_cmd,
                                                     swig_calc_children,
                                                     swig_get_child_index,
                                                     swig_get_index_child,
@@ -152,6 +155,7 @@ ScriptInterpreter::InitializeInterpreter
                                                     swig_mighthavechildren_provider,
                                                     swig_getvalue_provider,
                                                     swig_call_command,
+                                                    swig_call_command_object,
                                                     swig_call_module_init,
                                                     swig_create_os_plugin,
                                                     swig_run_script_keyword_process,

Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=232136&r1=232135&r2=232136&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Thu Mar 12 21:20:41 2015
@@ -54,6 +54,7 @@ static ScriptInterpreter::SWIGBreakpoint
 static ScriptInterpreter::SWIGWatchpointCallbackFunction g_swig_watchpoint_callback = nullptr;
 static ScriptInterpreter::SWIGPythonTypeScriptCallbackFunction g_swig_typescript_callback = nullptr;
 static ScriptInterpreter::SWIGPythonCreateSyntheticProvider g_swig_synthetic_script = nullptr;
+static ScriptInterpreter::SWIGPythonCreateCommandObject g_swig_create_cmd = nullptr;
 static ScriptInterpreter::SWIGPythonCalculateNumChildren g_swig_calc_children = nullptr;
 static ScriptInterpreter::SWIGPythonGetChildAtIndex g_swig_get_child_index = nullptr;
 static ScriptInterpreter::SWIGPythonGetIndexOfChildWithName g_swig_get_index_child = nullptr;
@@ -63,6 +64,7 @@ static ScriptInterpreter::SWIGPythonUpda
 static ScriptInterpreter::SWIGPythonMightHaveChildrenSynthProviderInstance g_swig_mighthavechildren_provider = nullptr;
 static ScriptInterpreter::SWIGPythonGetValueSynthProviderInstance g_swig_getvalue_provider = nullptr;
 static ScriptInterpreter::SWIGPythonCallCommand g_swig_call_command = nullptr;
+static ScriptInterpreter::SWIGPythonCallCommandObject g_swig_call_command_object = nullptr;
 static ScriptInterpreter::SWIGPythonCallModuleInit g_swig_call_module_init = nullptr;
 static ScriptInterpreter::SWIGPythonCreateOSPlugin g_swig_create_os_plugin = nullptr;
 static ScriptInterpreter::SWIGPythonScriptKeyword_Process g_swig_run_script_keyword_process = nullptr;
@@ -1807,6 +1809,29 @@ ScriptInterpreterPython::CreateSynthetic
     return MakeScriptObject(ret_val);
 }
 
+lldb::ScriptInterpreterObjectSP
+ScriptInterpreterPython::CreateScriptCommandObject (const char *class_name)
+{
+    DebuggerSP debugger_sp(GetCommandInterpreter().GetDebugger().shared_from_this());
+    
+    if (class_name == nullptr || class_name[0] == '\0')
+        return lldb::ScriptInterpreterObjectSP();
+    
+    if (!debugger_sp.get())
+        return lldb::ScriptInterpreterObjectSP();
+    
+    void* ret_val;
+    
+    {
+        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+        ret_val = g_swig_create_cmd (class_name,
+                                     m_dictionary_name.c_str(),
+                                     debugger_sp);
+    }
+    
+    return MakeScriptObject(ret_val);
+}
+
 bool
 ScriptInterpreterPython::GenerateTypeScriptFunction (const char* oneliner, std::string& output, const void* name_token)
 {
@@ -2680,6 +2705,62 @@ ScriptInterpreterPython::RunScriptBasedC
     return ret_val;
 }
 
+bool
+ScriptInterpreterPython::RunScriptBasedCommand (lldb::ScriptInterpreterObjectSP impl_obj_sp,
+                                                const char* args,
+                                                ScriptedCommandSynchronicity synchronicity,
+                                                lldb_private::CommandReturnObject& cmd_retobj,
+                                                Error& error,
+                                                const lldb_private::ExecutionContext& exe_ctx)
+{
+    if (!impl_obj_sp || !impl_obj_sp->GetObject())
+    {
+        error.SetErrorString("no function to execute");
+        return false;
+    }
+    
+    if (!g_swig_call_command_object)
+    {
+        error.SetErrorString("no helper function to run scripted commands");
+        return false;
+    }
+    
+    lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();
+    lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
+    
+    if (!debugger_sp.get())
+    {
+        error.SetErrorString("invalid Debugger pointer");
+        return false;
+    }
+    
+    bool ret_val = false;
+    
+    std::string err_msg;
+    
+    {
+        Locker py_lock(this,
+                       Locker::AcquireLock | Locker::InitSession | (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
+                       Locker::FreeLock    | Locker::TearDownSession);
+        
+        SynchronicityHandler synch_handler(debugger_sp,
+                                           synchronicity);
+        
+        ret_val = g_swig_call_command_object      (impl_obj_sp->GetObject(),
+                                                   debugger_sp,
+                                                   args,
+                                                   cmd_retobj,
+                                                   exe_ctx_ref_sp);
+    }
+    
+    if (!ret_val)
+        error.SetErrorString("unable to execute script function");
+    else
+        error.Clear();
+
+    return ret_val;
+}
+
 // in Python, a special attribute __doc__ contains the docstring
 // for an object (function, method, class, ...) if any is defined
 // Otherwise, the attribute's value is None
@@ -2727,6 +2808,7 @@ ScriptInterpreterPython::InitializeInter
                                                 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,
@@ -2736,6 +2818,7 @@ ScriptInterpreterPython::InitializeInter
                                                 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,
                                                 SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,
@@ -2752,6 +2835,7 @@ ScriptInterpreterPython::InitializeInter
     g_swig_watchpoint_callback = swig_watchpoint_callback;
     g_swig_typescript_callback = swig_typescript_callback;
     g_swig_synthetic_script = swig_synthetic_script;
+    g_swig_create_cmd = swig_create_cmd;
     g_swig_calc_children = swig_calc_children;
     g_swig_get_child_index = swig_get_child_index;
     g_swig_get_index_child = swig_get_index_child;
@@ -2761,6 +2845,7 @@ ScriptInterpreterPython::InitializeInter
     g_swig_mighthavechildren_provider = swig_mighthavechildren_provider;
     g_swig_getvalue_provider = swig_getvalue_provider;
     g_swig_call_command = swig_call_command;
+    g_swig_call_command_object = swig_call_command_object;
     g_swig_call_module_init = swig_call_module_init;
     g_swig_create_os_plugin = swig_create_os_plugin;
     g_swig_run_script_keyword_process = swig_run_script_keyword_process;





More information about the lldb-commits mailing list