diff options
Diffstat (limited to 'lldb')
-rw-r--r-- | lldb/include/lldb/Breakpoint/BreakpointOptions.h | 2 | ||||
-rw-r--r-- | lldb/include/lldb/Core/FormatClasses.h | 14 | ||||
-rw-r--r-- | lldb/include/lldb/Interpreter/ScriptInterpreter.h | 26 | ||||
-rw-r--r-- | lldb/include/lldb/Interpreter/ScriptInterpreterPython.h | 31 | ||||
-rw-r--r-- | lldb/source/API/SBTypeCategory.cpp | 12 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectBreakpointCommand.cpp | 4 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectCommands.cpp | 16 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectType.cpp | 45 | ||||
-rw-r--r-- | lldb/source/Core/FormatClasses.cpp | 33 | ||||
-rw-r--r-- | lldb/source/Interpreter/ScriptInterpreterPython.cpp | 477 |
10 files changed, 224 insertions, 436 deletions
diff --git a/lldb/include/lldb/Breakpoint/BreakpointOptions.h b/lldb/include/lldb/Breakpoint/BreakpointOptions.h index b97593a6ddd..7a6100b05ff 100644 --- a/lldb/include/lldb/Breakpoint/BreakpointOptions.h +++ b/lldb/include/lldb/Breakpoint/BreakpointOptions.h @@ -220,7 +220,7 @@ public: } StringList user_source; - StringList script_source; + std::string script_source; bool stop_on_error; }; diff --git a/lldb/include/lldb/Core/FormatClasses.h b/lldb/include/lldb/Core/FormatClasses.h index f0af7e70f07..8938e570c7a 100644 --- a/lldb/include/lldb/Core/FormatClasses.h +++ b/lldb/include/lldb/Core/FormatClasses.h @@ -636,7 +636,7 @@ public: { private: std::string m_python_class; - void *m_wrapper; // Wraps PyObject. + lldb::ScriptInterpreterObjectSP m_wrapper_sp; ScriptInterpreter *m_interpreter; public: @@ -649,9 +649,9 @@ public: virtual uint32_t CalculateNumChildren() { - if (m_wrapper == NULL || m_interpreter == NULL) + if (!m_wrapper_sp || m_interpreter == NULL) return 0; - return m_interpreter->CalculateNumChildren(m_wrapper); + return m_interpreter->CalculateNumChildren(m_wrapper_sp); } virtual lldb::ValueObjectSP @@ -660,18 +660,18 @@ public: virtual void Update() { - if (m_wrapper == NULL || m_interpreter == NULL) + if (!m_wrapper_sp || m_interpreter == NULL) return; - m_interpreter->UpdateSynthProviderInstance(m_wrapper); + m_interpreter->UpdateSynthProviderInstance(m_wrapper_sp); } virtual uint32_t GetIndexOfChildWithName (const ConstString &name) { - if (m_wrapper == NULL || m_interpreter == NULL) + if (!m_wrapper_sp || m_interpreter == NULL) return UINT32_MAX; - return m_interpreter->GetIndexOfChildWithName(m_wrapper, name.GetCString()); + return m_interpreter->GetIndexOfChildWithName(m_wrapper_sp, name.GetCString()); } typedef SHARED_PTR(SyntheticChildrenFrontEnd) SharedPointer; diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h index 4bd41d053b7..4015f91c510 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -142,50 +142,50 @@ public: } virtual bool - GenerateBreakpointCommandCallbackData (StringList &input, StringList &output) + GenerateBreakpointCommandCallbackData (StringList &input, std::string& output) { return false; } virtual bool - GenerateTypeScriptFunction (const char* oneliner, StringList &output, void* name_token = NULL) + GenerateTypeScriptFunction (const char* oneliner, std::string& output, void* name_token = NULL) { return false; } virtual bool - GenerateTypeScriptFunction (StringList &input, StringList &output, void* name_token = NULL) + GenerateTypeScriptFunction (StringList &input, std::string& output, void* name_token = NULL) { return false; } virtual bool - GenerateScriptAliasFunction (StringList &input, StringList &output) + GenerateScriptAliasFunction (StringList &input, std::string& output) { return false; } virtual bool - GenerateTypeSynthClass (StringList &input, StringList &output, void* name_token = NULL) + GenerateTypeSynthClass (StringList &input, std::string& output, void* name_token = NULL) { return false; } virtual bool - GenerateTypeSynthClass (const char* oneliner, StringList &output, void* name_token = NULL) + GenerateTypeSynthClass (const char* oneliner, std::string& output, void* name_token = NULL) { return false; } - virtual void* + virtual lldb::ScriptInterpreterObjectSP CreateSyntheticScriptedProvider (std::string class_name, lldb::ValueObjectSP valobj) { - return NULL; + return lldb::ScriptInterpreterObjectSP(); } virtual bool - GenerateFunction(std::string& signature, StringList &input, StringList &output) + GenerateFunction(const char *signature, const StringList &input) { return false; } @@ -212,25 +212,25 @@ public: } virtual uint32_t - CalculateNumChildren (void *implementor) + CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor) { return 0; } virtual lldb::ValueObjectSP - GetChildAtIndex (void *implementor, uint32_t idx) + GetChildAtIndex (const lldb::ScriptInterpreterObjectSP& implementor, uint32_t idx) { return lldb::ValueObjectSP(); } virtual int - GetIndexOfChildWithName (void *implementor, const char* child_name) + GetIndexOfChildWithName (const lldb::ScriptInterpreterObjectSP& implementor, const char* child_name) { return UINT32_MAX; } virtual void - UpdateSynthProviderInstance (void* implementor) + UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor) { } diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h b/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h index afd713f63b8..f51fa428b54 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h @@ -56,36 +56,36 @@ public: ExportFunctionDefinitionToInterpreter (StringList &function_def); bool - GenerateTypeScriptFunction (StringList &input, StringList &output, void* name_token = NULL); + GenerateTypeScriptFunction (StringList &input, std::string& output, void* name_token = NULL); bool - GenerateTypeSynthClass (StringList &input, StringList &output, void* name_token = NULL); + GenerateTypeSynthClass (StringList &input, std::string& output, void* name_token = NULL); bool - GenerateTypeSynthClass (const char* oneliner, StringList &output, void* name_token = NULL); + GenerateTypeSynthClass (const char* oneliner, std::string& output, void* name_token = NULL); // use this if the function code is just a one-liner script bool - GenerateTypeScriptFunction (const char* oneliner, StringList &output, void* name_token = NULL); + GenerateTypeScriptFunction (const char* oneliner, std::string& output, void* name_token = NULL); virtual bool - GenerateScriptAliasFunction (StringList &input, StringList &output); + GenerateScriptAliasFunction (StringList &input, std::string& output); - void* + lldb::ScriptInterpreterObjectSP CreateSyntheticScriptedProvider (std::string class_name, lldb::ValueObjectSP valobj); virtual uint32_t - CalculateNumChildren (void *implementor); + CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor); virtual lldb::ValueObjectSP - GetChildAtIndex (void *implementor, uint32_t idx); + GetChildAtIndex (const lldb::ScriptInterpreterObjectSP& implementor, uint32_t idx); virtual int - GetIndexOfChildWithName (void *implementor, const char* child_name); + GetIndexOfChildWithName (const lldb::ScriptInterpreterObjectSP& implementor, const char* child_name); virtual void - UpdateSynthProviderInstance (void* implementor); + UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor); virtual bool RunScriptBasedCommand(const char* impl_function, @@ -95,10 +95,10 @@ public: Error& error); bool - GenerateFunction(std::string& signature, StringList &input, StringList &output); + GenerateFunction(const char *signature, const StringList &input); bool - GenerateBreakpointCommandCallbackData (StringList &input, StringList &output); + GenerateBreakpointCommandCallbackData (StringList &input, std::string& output); static size_t GenerateBreakpointOptionsCommandCallback (void *baton, @@ -269,9 +269,10 @@ private: lldb_utility::PseudoTerminal m_embedded_python_pty; lldb::InputReaderSP m_embedded_thread_input_reader_sp; FILE *m_dbg_stdout; - void *m_new_sysout; // This is a PyObject. - void *m_old_sysout; // This is a PyObject. - void *m_old_syserr; // This is a PyObject. + PyObject *m_new_sysout; + PyObject *m_old_sysout; + PyObject *m_old_syserr; + PyObject *m_run_one_line; std::string m_dictionary_name; TerminalState m_terminal_state; bool m_session_is_active; diff --git a/lldb/source/API/SBTypeCategory.cpp b/lldb/source/API/SBTypeCategory.cpp index 1543b5efe81..60d9ac1ede7 100644 --- a/lldb/source/API/SBTypeCategory.cpp +++ b/lldb/source/API/SBTypeCategory.cpp @@ -359,13 +359,13 @@ SBTypeCategory::AddTypeSummary (SBTypeNameSpecifier type_name, ScriptInterpreter* interpreter_ptr = debugger_sp->GetCommandInterpreter().GetScriptInterpreter(); if (interpreter_ptr) { - StringList output; - if (interpreter_ptr->GenerateTypeScriptFunction(input, output, name_token) && output.GetSize() > 0) + std::string output; + if (interpreter_ptr->GenerateTypeScriptFunction(input, output, name_token) && !output.empty()) { if (need_set) { need_set = false; - summary.SetFunctionName(output.GetStringAtIndex(0)); + summary.SetFunctionName(output.c_str()); } } } @@ -467,13 +467,13 @@ SBTypeCategory::AddTypeSynthetic (SBTypeNameSpecifier type_name, ScriptInterpreter* interpreter_ptr = debugger_sp->GetCommandInterpreter().GetScriptInterpreter(); if (interpreter_ptr) { - StringList output; - if (interpreter_ptr->GenerateTypeSynthClass(input, output, name_token) && output.GetSize() > 0) + std::string output; + if (interpreter_ptr->GenerateTypeSynthClass(input, output, name_token) && !output.empty()) { if (need_set) { need_set = false; - synth.SetClassName(output.GetStringAtIndex(0)); + synth.SetClassName(output.c_str()); } } } diff --git a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp index a7e98eaf06b..5ab93d72632 100644 --- a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp @@ -422,7 +422,7 @@ CommandObjectBreakpointCommandAdd::SetBreakpointCommandCallback (BreakpointOptio // The former is used to generate callback description (as in breakpoint command list) // while the latter is used for Python to interpret during the actual callback. data_ap->user_source.AppendString (oneliner); - data_ap->script_source.AppendString (oneliner); + data_ap->script_source.assign (oneliner); data_ap->stop_on_error = m_options.m_stop_on_error; BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release())); @@ -499,7 +499,7 @@ CommandObjectBreakpointCommandAdd::GenerateBreakpointCommandCallback if (bp_options_baton) { ((BreakpointOptions::CommandData *) bp_options_baton->m_data)->user_source.Clear(); - ((BreakpointOptions::CommandData *) bp_options_baton->m_data)->script_source.Clear(); + ((BreakpointOptions::CommandData *) bp_options_baton->m_data)->script_source.clear(); } } if (!batch_mode) diff --git a/lldb/source/Commands/CommandObjectCommands.cpp b/lldb/source/Commands/CommandObjectCommands.cpp index bb928d5b765..c881a6feea6 100644 --- a/lldb/source/Commands/CommandObjectCommands.cpp +++ b/lldb/source/Commands/CommandObjectCommands.cpp @@ -1571,33 +1571,25 @@ private: out_stream->Flush(); return; } - StringList funct_name_sl; + std::string funct_name_str; if (!interpreter->GenerateScriptAliasFunction (m_user_input, - funct_name_sl)) + funct_name_str)) { out_stream->Printf ("Unable to create function: no script attached.\n"); out_stream->Flush(); return; } - if (funct_name_sl.GetSize() == 0) + if (funct_name_str.empty()) { out_stream->Printf ("Unable to obtain a function name: no script attached.\n"); out_stream->Flush(); return; } - const char *funct_name = funct_name_sl.GetStringAtIndex(0); - if (!funct_name || !funct_name[0]) - { - out_stream->Printf ("Invalid function name: no script attached.\n"); - out_stream->Flush(); - return; - } - // everything should be fine now, let's add this alias CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter, m_cmd_name, - funct_name, + funct_name_str.c_str(), m_synchronous)); if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true)) diff --git a/lldb/source/Commands/CommandObjectType.cpp b/lldb/source/Commands/CommandObjectType.cpp index 90fdafca17f..0de6d9b4af7 100644 --- a/lldb/source/Commands/CommandObjectType.cpp +++ b/lldb/source/Commands/CommandObjectType.cpp @@ -824,32 +824,25 @@ public: out_stream->Flush(); return; } - StringList funct_name_sl; + std::string funct_name_str; if (!interpreter->GenerateTypeScriptFunction (options->m_user_source, - funct_name_sl)) + funct_name_str)) { out_stream->Printf ("Internal error #3: no script attached.\n"); out_stream->Flush(); return; } - if (funct_name_sl.GetSize() == 0) + if (funct_name_str.empty()) { out_stream->Printf ("Internal error #4: no script attached.\n"); out_stream->Flush(); return; } - const char *funct_name = funct_name_sl.GetStringAtIndex(0); - if (!funct_name || !funct_name[0]) - { - out_stream->Printf ("Internal error #5: no script attached.\n"); - out_stream->Flush(); - return; - } // now I have a valid function name, let's add this as script for every type in the list TypeSummaryImplSP script_format; script_format.reset(new ScriptSummaryFormat(options->m_flags, - funct_name, + funct_name_str.c_str(), options->m_user_source.CopyList(" ").c_str())); Error error; @@ -1068,32 +1061,25 @@ CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturn } StringList funct_sl; funct_sl << m_options.m_python_script.c_str(); - StringList funct_name_sl; + std::string funct_name_str; if (!interpreter->GenerateTypeScriptFunction (funct_sl, - funct_name_sl)) + funct_name_str)) { result.AppendError ("Internal error #2Q: no script attached.\n"); result.SetStatus (eReturnStatusFailed); return false; } - if (funct_name_sl.GetSize() == 0) + if (funct_name_str.empty()) { result.AppendError ("Internal error #3Q: no script attached.\n"); result.SetStatus (eReturnStatusFailed); return false; } - const char *funct_name = funct_name_sl.GetStringAtIndex(0); - if (!funct_name || !funct_name[0]) - { - result.AppendError ("Internal error #4Q: no script attached.\n"); - result.SetStatus (eReturnStatusFailed); - return false; - } std::string code = " " + m_options.m_python_script; script_format.reset(new ScriptSummaryFormat(m_options.m_flags, - funct_name, + funct_name_str.c_str(), code.c_str())); } else // use an InputReader to grab Python code from the user @@ -3314,27 +3300,20 @@ public: out_stream->Flush(); return; } - StringList class_name_sl; + std::string class_name_str; if (!interpreter->GenerateTypeSynthClass (options->m_user_source, - class_name_sl)) + class_name_str)) { out_stream->Printf ("Internal error #3: no script attached.\n"); out_stream->Flush(); return; } - if (class_name_sl.GetSize() == 0) + if (class_name_str.empty()) { out_stream->Printf ("Internal error #4: no script attached.\n"); out_stream->Flush(); return; } - const char *class_name = class_name_sl.GetStringAtIndex(0); - if (!class_name || !class_name[0]) - { - out_stream->Printf ("Internal error #5: no script attached.\n"); - out_stream->Flush(); - return; - } // everything should be fine now, let's add the synth provider class @@ -3342,7 +3321,7 @@ public: synth_provider.reset(new TypeSyntheticImpl(SyntheticChildren::Flags().SetCascades(options->m_cascade). SetSkipPointers(options->m_skip_pointers). SetSkipReferences(options->m_skip_references), - class_name)); + class_name_str.c_str())); lldb::TypeCategoryImplSP category; diff --git a/lldb/source/Core/FormatClasses.cpp b/lldb/source/Core/FormatClasses.cpp index 4dd51de8a2c..d3a23d10219 100644 --- a/lldb/source/Core/FormatClasses.cpp +++ b/lldb/source/Core/FormatClasses.cpp @@ -9,20 +9,6 @@ // C Includes -#ifdef LLDB_DISABLE_PYTHON - -struct PyObject; - -#else // #ifdef LLDB_DISABLE_PYTHON - -#if defined (__APPLE__) -#include <Python/Python.h> -#else -#include <Python.h> -#endif - -#endif // #ifdef LLDB_DISABLE_PYTHON - // C++ Includes #include <ostream> @@ -269,35 +255,30 @@ SyntheticArrayView::GetDescription() TypeSyntheticImpl::FrontEnd::FrontEnd(std::string pclass, lldb::ValueObjectSP be) : SyntheticChildrenFrontEnd(be), - m_python_class(pclass) + m_python_class(pclass), + m_wrapper_sp(), + m_interpreter(NULL) { if (be.get() == NULL) - { - m_interpreter = NULL; - m_wrapper = NULL; return; - } m_interpreter = m_backend->GetTargetSP()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); - if (m_interpreter == NULL) - m_wrapper = NULL; - else - m_wrapper = m_interpreter->CreateSyntheticScriptedProvider(m_python_class, m_backend); + if (m_interpreter != NULL) + m_wrapper_sp = m_interpreter->CreateSyntheticScriptedProvider(m_python_class, m_backend); } TypeSyntheticImpl::FrontEnd::~FrontEnd() { - Py_XDECREF((PyObject*)m_wrapper); } lldb::ValueObjectSP TypeSyntheticImpl::FrontEnd::GetChildAtIndex (uint32_t idx, bool can_create) { - if (m_wrapper == NULL || m_interpreter == NULL) + if (!m_wrapper_sp || !m_interpreter) return lldb::ValueObjectSP(); - return m_interpreter->GetChildAtIndex(m_wrapper, idx); + return m_interpreter->GetChildAtIndex(m_wrapper_sp, idx); } std::string diff --git a/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/lldb/source/Interpreter/ScriptInterpreterPython.cpp index 87cb97e7264..1653e92e9b5 100644 --- a/lldb/source/Interpreter/ScriptInterpreterPython.cpp +++ b/lldb/source/Interpreter/ScriptInterpreterPython.cpp @@ -240,6 +240,7 @@ ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interprete m_embedded_thread_input_reader_sp (), m_dbg_stdout (interpreter.GetDebugger().GetOutputFile().GetStream()), m_new_sysout (NULL), + m_run_one_line (NULL), m_dictionary_name (interpreter.GetDebugger().GetInstanceName().AsCString()), m_terminal_state (), m_session_is_active (false), @@ -417,6 +418,64 @@ ScriptInterpreterPython::EnterSession () PyErr_Clear (); } +static PyObject* +FindSessionDictionary (const char* dict_name) +{ + static std::map<ConstString,PyObject*> g_dict_map; + + ConstString dict(dict_name); + + std::map<ConstString,PyObject*>::iterator iter = g_dict_map.find(dict); + + if (iter != g_dict_map.end()) + return iter->second; + + PyObject *main_mod = PyImport_AddModule ("__main__"); + if (main_mod != NULL) + { + PyObject *main_dict = PyModule_GetDict (main_mod); + if ((main_dict != NULL) + && PyDict_Check (main_dict)) + { + // Go through the main dictionary looking for the correct python script interpreter dictionary + PyObject *key, *value; + Py_ssize_t pos = 0; + + while (PyDict_Next (main_dict, &pos, &key, &value)) + { + // We have stolen references to the key and value objects in the dictionary; we need to increment + // them now so that Python's garbage collector doesn't collect them out from under us. + Py_INCREF (key); + Py_INCREF (value); + if (strcmp (PyString_AsString (key), dict_name) == 0) + { + g_dict_map[dict] = value; + return value; + } + } + } + } + return NULL; +} + +static std::string +GenerateUniqueName (const char* base_name_wanted, + uint32_t& functions_counter, + void* name_token = NULL) +{ + StreamString sstr; + + if (!base_name_wanted) + return std::string(); + + if (!name_token) + sstr.Printf ("%s_%d", base_name_wanted, functions_counter++); + else + sstr.Printf ("%s_%p", base_name_wanted, name_token); + + return sstr.GetString(); +} + bool ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObject *result) { @@ -437,41 +496,18 @@ ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObjec if (command) { // Find the correct script interpreter dictionary in the main module. - PyObject *main_mod = PyImport_AddModule ("__main__"); - PyObject *script_interpreter_dict = NULL; - if (main_mod != NULL) + PyObject *script_interpreter_dict = FindSessionDictionary(m_dictionary_name.c_str()); + if (script_interpreter_dict != NULL) { - PyObject *main_dict = PyModule_GetDict (main_mod); - if ((main_dict != NULL) - && PyDict_Check (main_dict)) + PyObject *pfunc = (PyObject*)m_run_one_line; + PyObject *pmod = PyImport_AddModule ("embedded_interpreter"); + if (pmod != NULL) { - // Go through the main dictionary looking for the correct python script interpreter dictionary - PyObject *key, *value; - Py_ssize_t pos = 0; - - while (PyDict_Next (main_dict, &pos, &key, &value)) + PyObject *pmod_dict = PyModule_GetDict (pmod); + if ((pmod_dict != NULL) + && PyDict_Check (pmod_dict)) { - // We have stolen references to the key and value objects in the dictionary; we need to increment - // them now so that Python's garbage collector doesn't collect them out from under us. - Py_INCREF (key); - Py_INCREF (value); - if (strcmp (PyString_AsString (key), m_dictionary_name.c_str()) == 0) - { - script_interpreter_dict = value; - break; - } - } - } - - if (script_interpreter_dict != NULL) - { - PyObject *pfunc = NULL; - PyObject *pmod = PyImport_AddModule ("embedded_interpreter"); - if (pmod != NULL) - { - PyObject *pmod_dict = PyModule_GetDict (pmod); - if ((pmod_dict != NULL) - && PyDict_Check (pmod_dict)) + if (!pfunc) { PyObject *key, *value; Py_ssize_t pos = 0; @@ -486,33 +522,31 @@ ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObjec break; } } - - PyObject *string_arg = PyString_FromString (command); - if (pfunc && string_arg && PyCallable_Check (pfunc)) + m_run_one_line = pfunc; + } + + if (pfunc && PyCallable_Check (pfunc)) + { + PyObject *pargs = Py_BuildValue("(Os)",script_interpreter_dict,command); + if (pargs != NULL) { - PyObject *pargs = PyTuple_New (2); - if (pargs != NULL) + PyObject *pvalue = PyObject_CallObject (pfunc, pargs); + Py_DECREF (pargs); + if (pvalue != NULL) + { + Py_DECREF (pvalue); + success = true; + } + else if (PyErr_Occurred ()) { - PyTuple_SetItem (pargs, 0, script_interpreter_dict); - PyTuple_SetItem (pargs, 1, string_arg); - PyObject *pvalue = PyObject_CallObject (pfunc, pargs); - Py_DECREF (pargs); - if (pvalue != NULL) - { - Py_DECREF (pvalue); - success = true; - } - else if (PyErr_Occurred ()) - { - PyErr_Print(); - PyErr_Clear(); - } + PyErr_Print(); + PyErr_Clear(); } } } } - Py_INCREF (script_interpreter_dict); } + Py_INCREF (script_interpreter_dict); } if (success) @@ -739,25 +773,8 @@ ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string, bool should_decrement_locals = false; int success; - if (PyDict_Check (globals)) - { - PyObject *key, *value; - Py_ssize_t pos = 0; - - int i = 0; - while (PyDict_Next (globals, &pos, &key, &value)) - { - // We have stolen references to the key and value objects in the dictionary; we need to increment them now - // so that Python's garbage collector doesn't collect them out from under us. - Py_INCREF (key); - Py_INCREF (value); - char *c_str = PyString_AsString (key); - if (strcmp (c_str, m_dictionary_name.c_str()) == 0) - locals = value; - ++i; - } - } - + locals = FindSessionDictionary(m_dictionary_name.c_str()); + if (locals == NULL) { locals = PyObject_GetAttrString (globals, m_dictionary_name.c_str()); @@ -918,22 +935,8 @@ ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string) PyObject *py_error = NULL; bool should_decrement_locals = false; - if (PyDict_Check (globals)) - { - PyObject *key, *value; - Py_ssize_t pos = 0; - - while (PyDict_Next (globals, &pos, &key, &value)) - { - // We have stolen references to the key and value objects in the dictionary; we need to increment them now - // so that Python's garbage collector doesn't collect them out from under us. - Py_INCREF (key); - Py_INCREF (value); - if (strcmp (PyString_AsString (key), m_dictionary_name.c_str()) == 0) - locals = value; - } - } - + locals = FindSessionDictionary(m_dictionary_name.c_str()); + if (locals == NULL) { locals = PyObject_GetAttrString (globals, m_dictionary_name.c_str()); @@ -1064,11 +1067,8 @@ ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback if (interpreter->GenerateBreakpointCommandCallbackData (data_ap->user_source, data_ap->script_source)) { - if (data_ap->script_source.GetSize() == 1) - { - BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release())); - bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp); - } + BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release())); + bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp); } else if (!batch_mode) { @@ -1141,11 +1141,8 @@ ScriptInterpreterPython::SetBreakpointCommandCallback (BreakpointOptions *bp_opt if (GenerateBreakpointCommandCallbackData (data_ap->user_source, data_ap->script_source)) { - if (data_ap->script_source.GetSize() == 1) - { - BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release())); - bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp); - } + BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release())); + bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp); } return; @@ -1155,32 +1152,24 @@ bool ScriptInterpreterPython::ExportFunctionDefinitionToInterpreter (StringList &function_def) { // Convert StringList to one long, newline delimited, const char *. - std::string function_def_string; - - int num_lines = function_def.GetSize(); - - for (int i = 0; i < num_lines; ++i) - { - function_def_string.append (function_def.GetStringAtIndex(i)); - if (function_def_string.at (function_def_string.length() - 1) != '\n') - function_def_string.append ("\n"); - - } + std::string function_def_string(function_def.CopyList()); return ExecuteMultipleLines (function_def_string.c_str()); } -// TODO move both GenerateTypeScriptFunction and GenerateBreakpointCommandCallbackData to actually -// use this code to generate their functions bool -ScriptInterpreterPython::GenerateFunction(std::string& signature, StringList &input, StringList &output) +ScriptInterpreterPython::GenerateFunction(const char *signature, const StringList &input) { int num_lines = input.GetSize (); if (num_lines == 0) return false; + + if (!signature || *signature == 0) + return false; + StreamString sstr; StringList auto_generated_function; - auto_generated_function.AppendString (signature.c_str()); + auto_generated_function.AppendString (signature); auto_generated_function.AppendString (" global_dict = globals()"); // Grab the global dictionary auto_generated_function.AppendString (" new_keys = dict.keys()"); // Make a list of keys in the session dict auto_generated_function.AppendString (" old_keys = global_dict.keys()"); // Save list of keys in global dict @@ -1209,14 +1198,11 @@ ScriptInterpreterPython::GenerateFunction(std::string& signature, StringList &in } -// this implementation is identical to GenerateBreakpointCommandCallbackData (apart from the name -// given to generated functions, of course) bool -ScriptInterpreterPython::GenerateTypeScriptFunction (StringList &user_input, StringList &output, void* name_token) +ScriptInterpreterPython::GenerateTypeScriptFunction (StringList &user_input, std::string& output, void* name_token) { - static int num_created_functions = 0; + static uint32_t num_created_functions = 0; user_input.RemoveBlankLines (); - int num_lines = user_input.GetSize (); StreamString sstr; // Check to see if we have any data; if not, just return. @@ -1226,125 +1212,45 @@ ScriptInterpreterPython::GenerateTypeScriptFunction (StringList &user_input, Str // Take what the user wrote, wrap it all up inside one big auto-generated Python function, passing in the // ValueObject as parameter to the function. - if (!name_token) - sstr.Printf ("lldb_autogen_python_type_print_func_%d", num_created_functions); - else - sstr.Printf ("lldb_gen_python_type_print_func_%p", name_token); - ++num_created_functions; - std::string auto_generated_function_name = sstr.GetData(); - - sstr.Clear(); - StringList auto_generated_function; - - // Create the function name & definition string. - + std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_type_print_func", num_created_functions, name_token)); sstr.Printf ("def %s (valobj, dict):", auto_generated_function_name.c_str()); - auto_generated_function.AppendString (sstr.GetData()); - // Pre-pend code for setting up the session dictionary. - - auto_generated_function.AppendString (" global_dict = globals()"); // Grab the global dictionary - auto_generated_function.AppendString (" new_keys = dict.keys()"); // Make a list of keys in the session dict - auto_generated_function.AppendString (" old_keys = global_dict.keys()"); // Save list of keys in global dict - auto_generated_function.AppendString (" global_dict.update (dict)"); // Add the session dictionary to the - // global dictionary. - - // Wrap everything up inside the function, increasing the indentation. - - for (int i = 0; i < num_lines; ++i) - { - sstr.Clear (); - sstr.Printf (" %s", user_input.GetStringAtIndex (i)); - auto_generated_function.AppendString (sstr.GetData()); - } - - // Append code to clean up the global dictionary and update the session dictionary (all updates in the function - // got written to the values in the global dictionary, not the session dictionary). - - auto_generated_function.AppendString (" for key in new_keys:"); // Iterate over all the keys from session dict - auto_generated_function.AppendString (" dict[key] = global_dict[key]"); // Update session dict values - auto_generated_function.AppendString (" if key not in old_keys:"); // If key was not originally in global dict - auto_generated_function.AppendString (" del global_dict[key]"); // ...then remove key/value from global dict - - // Verify that the results are valid Python. - - if (!ExportFunctionDefinitionToInterpreter (auto_generated_function)) + if (!GenerateFunction(sstr.GetData(), user_input)) return false; - + // Store the name of the auto-generated function to be called. - - output.AppendString (auto_generated_function_name.c_str()); + output.assign(auto_generated_function_name); return true; } bool -ScriptInterpreterPython::GenerateScriptAliasFunction (StringList &user_input, StringList &output) +ScriptInterpreterPython::GenerateScriptAliasFunction (StringList &user_input, std::string &output) { - static int num_created_functions = 0; + static uint32_t num_created_functions = 0; user_input.RemoveBlankLines (); - int num_lines = user_input.GetSize (); StreamString sstr; // Check to see if we have any data; if not, just return. if (user_input.GetSize() == 0) return false; - // Take what the user wrote, wrap it all up inside one big auto-generated Python function, passing in the - // required data as parameters to the function. - - sstr.Printf ("lldb_autogen_python_cmd_alias_func_%d", num_created_functions); - ++num_created_functions; - std::string auto_generated_function_name = sstr.GetData(); - - sstr.Clear(); - StringList auto_generated_function; - - // Create the function name & definition string. - + std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_cmd_alias_func", num_created_functions)); + sstr.Printf ("def %s (debugger, args, result, dict):", auto_generated_function_name.c_str()); - auto_generated_function.AppendString (sstr.GetData()); - - // Pre-pend code for setting up the session dictionary. - - auto_generated_function.AppendString (" global_dict = globals()"); // Grab the global dictionary - auto_generated_function.AppendString (" new_keys = dict.keys()"); // Make a list of keys in the session dict - auto_generated_function.AppendString (" old_keys = global_dict.keys()"); // Save list of keys in global dict - auto_generated_function.AppendString (" global_dict.update (dict)"); // Add the session dictionary to the - // global dictionary. - - // Wrap everything up inside the function, increasing the indentation. - - for (int i = 0; i < num_lines; ++i) - { - sstr.Clear (); - sstr.Printf (" %s", user_input.GetStringAtIndex (i)); - auto_generated_function.AppendString (sstr.GetData()); - } - - // Append code to clean up the global dictionary and update the session dictionary (all updates in the function - // got written to the values in the global dictionary, not the session dictionary). - - auto_generated_function.AppendString (" for key in new_keys:"); // Iterate over all the keys from session dict - auto_generated_function.AppendString (" dict[key] = global_dict[key]"); // Update session dict values - auto_generated_function.AppendString (" if key not in old_keys:"); // If key was not originally in global dict - auto_generated_function.AppendString (" del global_dict[key]"); // ...then remove key/value from global dict - // Verify that the results are valid Python. - - if (!ExportFunctionDefinitionToInterpreter (auto_generated_function)) + if (!GenerateFunction(sstr.GetData(),user_input)) return false; // Store the name of the auto-generated function to be called. - - output.AppendString (auto_generated_function_name.c_str()); + output.assign(auto_generated_function_name); return true; } bool -ScriptInterpreterPython::GenerateTypeSynthClass (StringList &user_input, StringList &output, void* name_token) +ScriptInterpreterPython::GenerateTypeSynthClass (StringList &user_input, std::string &output, void* name_token) { - static int num_created_classes = 0; + static uint32_t num_created_classes = 0; user_input.RemoveBlankLines (); int num_lines = user_input.GetSize (); StreamString sstr; @@ -1355,14 +1261,8 @@ ScriptInterpreterPython::GenerateTypeSynthClass (StringList &user_input, StringL // Wrap all user input into a Python class - if (!name_token) - sstr.Printf ("lldb_autogen_python_type_synth_class_%d", num_created_classes); - else - sstr.Printf ("lldb_gen_python_type_synth_class_%p", name_token); - ++num_created_classes; - std::string auto_generated_class_name = sstr.GetData(); + std::string auto_generated_class_name(GenerateUniqueName("lldb_autogen_python_type_synth_class",num_created_classes,name_token)); - sstr.Clear(); StringList auto_generated_class; // Create the function name & definition string. @@ -1388,32 +1288,32 @@ ScriptInterpreterPython::GenerateTypeSynthClass (StringList &user_input, StringL // Store the name of the auto-generated class - output.AppendString (auto_generated_class_name.c_str()); + output.assign(auto_generated_class_name); return true; } -void* +lldb::ScriptInterpreterObjectSP ScriptInterpreterPython::CreateSyntheticScriptedProvider (std::string class_name, lldb::ValueObjectSP valobj) { if (class_name.empty()) - return NULL; + return lldb::ScriptInterpreterObjectSP(); if (!valobj.get()) - return NULL; + return lldb::ScriptInterpreterObjectSP(); ExecutionContext exe_ctx (valobj->GetExecutionContextRef()); Target *target = exe_ctx.GetTargetPtr(); if (!target) - return NULL; + return lldb::ScriptInterpreterObjectSP(); Debugger &debugger = target->GetDebugger(); ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter(); ScriptInterpreterPython *python_interpreter = (ScriptInterpreterPython *) script_interpreter; if (!script_interpreter) - return NULL; + return lldb::ScriptInterpreterObjectSP(); void* ret_val; @@ -1424,11 +1324,11 @@ ScriptInterpreterPython::CreateSyntheticScriptedProvider (std::string class_name valobj); } - return ret_val; + return MakeScriptObject(ret_val); } bool -ScriptInterpreterPython::GenerateTypeScriptFunction (const char* oneliner, StringList &output, void* name_token) +ScriptInterpreterPython::GenerateTypeScriptFunction (const char* oneliner, std::string& output, void* name_token) { StringList input; input.SplitIntoLines(oneliner, strlen(oneliner)); @@ -1436,7 +1336,7 @@ ScriptInterpreterPython::GenerateTypeScriptFunction (const char* oneliner, Strin } bool -ScriptInterpreterPython::GenerateTypeSynthClass (const char* oneliner, StringList &output, void* name_token) +ScriptInterpreterPython::GenerateTypeSynthClass (const char* oneliner, std::string& output, void* name_token) { StringList input; input.SplitIntoLines(oneliner, strlen(oneliner)); @@ -1445,111 +1345,26 @@ ScriptInterpreterPython::GenerateTypeSynthClass (const char* oneliner, StringLis bool -ScriptInterpreterPython::GenerateBreakpointCommandCallbackData (StringList &user_input, StringList &callback_data) +ScriptInterpreterPython::GenerateBreakpointCommandCallbackData (StringList &user_input, std::string& output) { - static int num_created_functions = 0; + static uint32_t num_created_functions = 0; user_input.RemoveBlankLines (); - int num_lines = user_input.GetSize (); StreamString sstr; - // Check to see if we have any data; if not, just return. if (user_input.GetSize() == 0) return false; - // Take what the user wrote, wrap it all up inside one big auto-generated Python function, passing in the - // frame and breakpoint location as parameters to the function. - - - sstr.Printf ("lldb_autogen_python_bp_callback_func_%d", num_created_functions); - ++num_created_functions; - std::string auto_generated_function_name = sstr.GetData(); - - sstr.Clear(); - StringList auto_generated_function; - - // Create the function name & definition string. - + std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_bp_callback_func_",num_created_functions)); sstr.Printf ("def %s (frame, bp_loc, dict):", auto_generated_function_name.c_str()); - auto_generated_function.AppendString (sstr.GetData()); - // Pre-pend code for setting up the session dictionary. - - auto_generated_function.AppendString (" global_dict = globals()"); // Grab the global dictionary - auto_generated_function.AppendString (" new_keys = dict.keys()"); // Make a list of keys in the session dict - auto_generated_function.AppendString (" old_keys = global_dict.keys()"); // Save list of keys in global dict - auto_generated_function.AppendString (" global_dict.update (dict)"); // Add the session dictionary to the - // global dictionary. - - // Wrap everything up inside the function, increasing the indentation. - - for (int i = 0; i < num_lines; ++i) - { - sstr.Clear (); - sstr.Printf (" %s", user_input.GetStringAtIndex (i)); - auto_generated_function.AppendString (sstr.GetData()); - } - - // Append code to clean up the global dictionary and update the session dictionary (all updates in the function - // got written to the values in the global dictionary, not the session dictionary). - - auto_generated_function.AppendString (" for key in new_keys:"); // Iterate over all the keys from session dict - auto_generated_function.AppendString (" dict[key] = global_dict[key]"); // Update session dict values - auto_generated_function.AppendString (" if key not in old_keys:"); // If key was not originally in global dict - auto_generated_function.AppendString (" del global_dict[key]"); // ...then remove key/value from global dict - - // Verify that the results are valid Python. - - if (!ExportFunctionDefinitionToInterpreter (auto_generated_function)) - { + if (!GenerateFunction(sstr.GetData(), user_input)) return false; - } - + // Store the name of the auto-generated function to be called. - - callback_data.AppendString (auto_generated_function_name.c_str()); + output.assign(auto_generated_function_name); return true; } -static PyObject* -FindSessionDictionary(const char* dict_name) -{ - static std::map<ConstString,PyObject*> g_dict_map; - - ConstString dict(dict_name); - - std::map<ConstString,PyObject*>::iterator iter = g_dict_map.find(dict); - - if (iter != g_dict_map.end()) - return iter->second; - - PyObject *main_mod = PyImport_AddModule ("__main__"); - if (main_mod != NULL) - { - PyObject *main_dict = PyModule_GetDict (main_mod); - if ((main_dict != NULL) - && PyDict_Check (main_dict)) - { - // Go through the main dictionary looking for the correct python script interpreter dictionary - PyObject *key, *value; - Py_ssize_t pos = 0; - - while (PyDict_Next (main_dict, &pos, &key, &value)) - { - // We have stolen references to the key and value objects in the dictionary; we need to increment - // them now so that Python's garbage collector doesn't collect them out from under us. - Py_INCREF (key); - Py_INCREF (value); - if (strcmp (PyString_AsString (key), dict_name) == 0) - { - g_dict_map[dict] = value; - return value; - } - } - } - } - return NULL; -} - bool ScriptInterpreterPython::GetScriptedSummary (const char *python_function_name, lldb::ValueObjectSP valobj, @@ -1607,7 +1422,7 @@ ScriptInterpreterPython::BreakpointCallbackFunction ) { BreakpointOptions::CommandData *bp_option_data = (BreakpointOptions::CommandData *) baton; - const char *python_function_name = bp_option_data->script_source.GetStringAtIndex (0); + const char *python_function_name = bp_option_data->script_source.c_str(); if (!context) return true; @@ -1745,8 +1560,13 @@ ScriptInterpreterPython::RunEmbeddedPythonInterpreter (lldb::thread_arg_t baton) } uint32_t -ScriptInterpreterPython::CalculateNumChildren (void *implementor) +ScriptInterpreterPython::CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor_sp) { + if (!implementor_sp) + return 0; + + void* implementor = implementor_sp->GetObject(); + if (!implementor) return 0; @@ -1764,8 +1584,13 @@ ScriptInterpreterPython::CalculateNumChildren (void *implementor) } lldb::ValueObjectSP -ScriptInterpreterPython::GetChildAtIndex (void *implementor, uint32_t idx) +ScriptInterpreterPython::GetChildAtIndex (const lldb::ScriptInterpreterObjectSP& implementor_sp, uint32_t idx) { + if (!implementor_sp) + return lldb::ValueObjectSP(); + + void* implementor = implementor_sp->GetObject(); + if (!implementor) return lldb::ValueObjectSP(); @@ -1797,8 +1622,13 @@ ScriptInterpreterPython::GetChildAtIndex (void *implementor, uint32_t idx) } int -ScriptInterpreterPython::GetIndexOfChildWithName (void *implementor, const char* child_name) +ScriptInterpreterPython::GetIndexOfChildWithName (const lldb::ScriptInterpreterObjectSP& implementor_sp, const char* child_name) { + if (!implementor_sp) + return UINT32_MAX; + + void* implementor = implementor_sp->GetObject(); + if (!implementor) return UINT32_MAX; @@ -1816,8 +1646,13 @@ ScriptInterpreterPython::GetIndexOfChildWithName (void *implementor, const char* } void -ScriptInterpreterPython::UpdateSynthProviderInstance (void* implementor) +ScriptInterpreterPython::UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor_sp) { + if (!implementor_sp) + return; + + void* implementor = implementor_sp->GetObject(); + if (!implementor) return; |