[Lldb-commits] [lldb] r152164 - in /lldb/trunk: include/lldb/Breakpoint/BreakpointOptions.h include/lldb/Core/FormatClasses.h include/lldb/Interpreter/ScriptInterpreter.h include/lldb/Interpreter/ScriptInterpreterPython.h source/API/SBTypeCategory.cpp source/Commands/CommandObjectBreakpointCommand.cpp source/Commands/CommandObjectCommands.cpp source/Commands/CommandObjectType.cpp source/Core/FormatClasses.cpp source/Interpreter/ScriptInterpreterPython.cpp
Enrico Granata
egranata at apple.com
Tue Mar 6 15:42:15 PST 2012
Author: enrico
Date: Tue Mar 6 17:42:15 2012
New Revision: 152164
URL: http://llvm.org/viewvc/llvm-project?rev=152164&view=rev
Log:
Using the new ScriptInterpreterObject in the implementation of synthetic children to enhance type safety
Several places in the ScriptInterpreter interface used StringList objects where an std::string would suffice - Fixed
Refactoring calls that generated special-purposes functions in the Python interpreter to use helper functions instead of duplicating blobs of code
Modified:
lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h
lldb/trunk/include/lldb/Core/FormatClasses.h
lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
lldb/trunk/source/API/SBTypeCategory.cpp
lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp
lldb/trunk/source/Commands/CommandObjectCommands.cpp
lldb/trunk/source/Commands/CommandObjectType.cpp
lldb/trunk/source/Core/FormatClasses.cpp
lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h?rev=152164&r1=152163&r2=152164&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h Tue Mar 6 17:42:15 2012
@@ -220,7 +220,7 @@
}
StringList user_source;
- StringList script_source;
+ std::string script_source;
bool stop_on_error;
};
Modified: lldb/trunk/include/lldb/Core/FormatClasses.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatClasses.h?rev=152164&r1=152163&r2=152164&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FormatClasses.h (original)
+++ lldb/trunk/include/lldb/Core/FormatClasses.h Tue Mar 6 17:42:15 2012
@@ -636,7 +636,7 @@
{
private:
std::string m_python_class;
- void *m_wrapper; // Wraps PyObject.
+ lldb::ScriptInterpreterObjectSP m_wrapper_sp;
ScriptInterpreter *m_interpreter;
public:
@@ -649,9 +649,9 @@
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 @@
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;
Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h?rev=152164&r1=152163&r2=152164&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h Tue Mar 6 17:42:15 2012
@@ -142,50 +142,50 @@
}
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 @@
}
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)
{
}
Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h?rev=152164&r1=152163&r2=152164&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h Tue Mar 6 17:42:15 2012
@@ -56,36 +56,36 @@
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 @@
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 @@
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;
Modified: lldb/trunk/source/API/SBTypeCategory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTypeCategory.cpp?rev=152164&r1=152163&r2=152164&view=diff
==============================================================================
--- lldb/trunk/source/API/SBTypeCategory.cpp (original)
+++ lldb/trunk/source/API/SBTypeCategory.cpp Tue Mar 6 17:42:15 2012
@@ -359,13 +359,13 @@
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 @@
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());
}
}
}
Modified: lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp?rev=152164&r1=152163&r2=152164&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp Tue Mar 6 17:42:15 2012
@@ -422,7 +422,7 @@
// 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 @@
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)
Modified: lldb/trunk/source/Commands/CommandObjectCommands.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectCommands.cpp?rev=152164&r1=152163&r2=152164&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectCommands.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectCommands.cpp Tue Mar 6 17:42:15 2012
@@ -1571,33 +1571,25 @@
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))
Modified: lldb/trunk/source/Commands/CommandObjectType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=152164&r1=152163&r2=152164&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectType.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectType.cpp Tue Mar 6 17:42:15 2012
@@ -824,32 +824,25 @@
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 @@
}
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 @@
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 @@
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;
Modified: lldb/trunk/source/Core/FormatClasses.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatClasses.cpp?rev=152164&r1=152163&r2=152164&view=diff
==============================================================================
--- lldb/trunk/source/Core/FormatClasses.cpp (original)
+++ lldb/trunk/source/Core/FormatClasses.cpp Tue Mar 6 17:42:15 2012
@@ -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 @@
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
Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=152164&r1=152163&r2=152164&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Tue Mar 6 17:42:15 2012
@@ -240,6 +240,7 @@
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 @@
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 @@
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 *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), m_dictionary_name.c_str()) == 0)
- {
- script_interpreter_dict = value;
- break;
- }
- }
- }
-
- if (script_interpreter_dict != NULL)
+ PyObject *script_interpreter_dict = FindSessionDictionary(m_dictionary_name.c_str());
+ if (script_interpreter_dict != NULL)
+ {
+ PyObject *pfunc = (PyObject*)m_run_one_line;
+ PyObject *pmod = PyImport_AddModule ("embedded_interpreter");
+ if (pmod != 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))
+ 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
-// 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 @@
// 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 @@
// 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 @@
// 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 @@
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 @@
}
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 @@
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 @@
)
{
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 @@
}
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 @@
}
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 @@
}
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 @@
}
void
-ScriptInterpreterPython::UpdateSynthProviderInstance (void* implementor)
+ScriptInterpreterPython::UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor_sp)
{
+ if (!implementor_sp)
+ return;
+
+ void* implementor = implementor_sp->GetObject();
+
if (!implementor)
return;
More information about the lldb-commits
mailing list