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


git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@152164 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Interpreter/ScriptInterpreterPython.cpp b/source/Interpreter/ScriptInterpreterPython.cpp
index 87cb97e..1653e92 100644
--- a/source/Interpreter/ScriptInterpreterPython.cpp
+++ b/source/Interpreter/ScriptInterpreterPython.cpp
@@ -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 *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 @@
                                 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)
                             {
-                                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();
-                                }
+                                Py_DECREF (pvalue);
+                                success = true;
+                            }
+                            else if (PyErr_Occurred ())
+                            {
+                                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;