summaryrefslogtreecommitdiffstats
path: root/lldb/source/Interpreter/ScriptInterpreterPython.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Interpreter/ScriptInterpreterPython.cpp')
-rw-r--r--lldb/source/Interpreter/ScriptInterpreterPython.cpp186
1 files changed, 141 insertions, 45 deletions
diff --git a/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/lldb/source/Interpreter/ScriptInterpreterPython.cpp
index ccdf7486ca4..246e3bd7b9a 100644
--- a/lldb/source/Interpreter/ScriptInterpreterPython.cpp
+++ b/lldb/source/Interpreter/ScriptInterpreterPython.cpp
@@ -54,6 +54,62 @@ static ScriptInterpreter::SWIGPythonUpdateSynthProviderInstance g_swig_update_pr
static ScriptInterpreter::SWIGPythonCallCommand g_swig_call_command = NULL;
static ScriptInterpreter::SWIGPythonCallModuleInit g_swig_call_module_init = NULL;
+// these are the Pythonic implementations of the required callbacks
+// these are scripting-language specific, which is why they belong here
+// we still need to use function pointers to them instead of relying
+// on linkage-time resolution because the SWIG stuff and this file
+// get built at different times
+extern "C" bool
+LLDBSwigPythonBreakpointCallbackFunction
+(
+ const char *python_function_name,
+ const char *session_dictionary_name,
+ const lldb::StackFrameSP& sb_frame,
+ const lldb::BreakpointLocationSP& sb_bp_loc
+ );
+
+extern "C" bool
+LLDBSwigPythonCallTypeScript
+(
+ const char *python_function_name,
+ void *session_dictionary,
+ const lldb::ValueObjectSP& valobj_sp,
+ void** pyfunct_wrapper,
+ std::string& retval
+ );
+
+extern "C" void*
+LLDBSwigPythonCreateSyntheticProvider
+(
+ const std::string python_class_name,
+ const char *session_dictionary_name,
+ const lldb::ValueObjectSP& valobj_sp
+ );
+
+
+extern "C" uint32_t LLDBSwigPython_CalculateNumChildren (void *implementor);
+extern "C" void* LLDBSwigPython_GetChildAtIndex (void *implementor, uint32_t idx);
+extern "C" int LLDBSwigPython_GetIndexOfChildWithName (void *implementor, const char* child_name);
+extern "C" void* LLDBSWIGPython_CastPyObjectToSBValue (void* data);
+extern "C" void LLDBSwigPython_UpdateSynthProviderInstance (void* implementor);
+
+extern "C" bool LLDBSwigPythonCallCommand
+(
+ const char *python_function_name,
+ const char *session_dictionary_name,
+ lldb::DebuggerSP& debugger,
+ const char* args,
+ std::string& err_msg,
+ lldb_private::CommandReturnObject& cmd_retobj
+ );
+
+extern "C" bool LLDBSwigPythonCallModuleInit
+(
+ const std::string python_module_name,
+ const char *session_dictionary_name,
+ lldb::DebuggerSP& debugger
+ );
+
static int
_check_and_flush (FILE *stream)
{
@@ -226,7 +282,7 @@ ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interprete
// WARNING: temporary code that loads Cocoa formatters - this should be done on a per-platform basis rather than loading the whole set
// and letting the individual formatter classes exploit APIs to check whether they can/cannot do their task
run_string.Clear();
- run_string.Printf ("run_one_line (%s, 'import CFString, CFArray, CFDictionary, NSData, NSMachPort, NSSet, NSNotification, NSException, CFBag, CFBinaryHeap, NSURL, NSBundle, NSNumber')", m_dictionary_name.c_str());
+ run_string.Printf ("run_one_line (%s, 'import CFString, CFArray, CFDictionary, NSData, NSMachPort, NSSet, NSNotification, NSException, CFBag, CFBinaryHeap, NSURL, NSBundle, NSNumber, NSDate')", m_dictionary_name.c_str());
PyRun_SimpleString (run_string.GetData());
int new_count = Debugger::TestDebuggerRefCount();
@@ -1454,44 +1510,88 @@ ScriptInterpreterPython::GenerateBreakpointCommandCallbackData (StringList &user
return true;
}
-std::string
-ScriptInterpreterPython::CallPythonScriptFunction (const char *python_function_name,
- lldb::ValueObjectSP valobj)
+static PyObject*
+FindSessionDictionary(const char* dict_name)
{
+ static std::map<ConstString,PyObject*> g_dict_map;
- if (!python_function_name || !(*python_function_name))
- return "<no function>";
+ ConstString dict(dict_name);
- if (!valobj.get())
- return "<no object>";
-
- ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
- Target *target = exe_ctx.GetTargetPtr();
+ std::map<ConstString,PyObject*>::iterator iter = g_dict_map.find(dict);
- if (!target)
- return "<no target>";
+ if (iter != g_dict_map.end())
+ return iter->second;
- Debugger &debugger = target->GetDebugger();
- ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
- ScriptInterpreterPython *python_interpreter = (ScriptInterpreterPython *) script_interpreter;
+ 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,
+ lldb::ScriptInterpreterObjectSP& callee_wrapper_sp,
+ std::string& retval)
+{
- if (!script_interpreter)
- return "<no python>";
+ Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
- std::string ret_val;
+ if (!valobj.get())
+ {
+ retval.assign("<no object>");
+ return false;
+ }
+
+ void* old_callee = (callee_wrapper_sp ? callee_wrapper_sp->GetObject() : NULL);
+ void* new_callee = old_callee;
+ bool ret_val;
if (python_function_name
&& *python_function_name)
{
{
- Locker py_lock(python_interpreter);
- ret_val = g_swig_typescript_callback (python_function_name,
- python_interpreter->m_dictionary_name.c_str(),
- valobj);
+ Locker py_lock(this);
+ {
+ Timer scoped_timer ("g_swig_typescript_callback","g_swig_typescript_callback");
+ ret_val = g_swig_typescript_callback (python_function_name,
+ FindSessionDictionary(m_dictionary_name.c_str()),
+ valobj,
+ &new_callee,
+ retval);
+ }
}
}
else
- return "<no function name>";
+ {
+ retval.assign("<no function name>");
+ return false;
+ }
+
+ if (new_callee && old_callee != new_callee)
+ callee_wrapper_sp = MakeScriptObject(new_callee);
return ret_val;
@@ -1822,6 +1922,12 @@ ScriptInterpreterPython::LoadScriptingModule (const char* pathname,
}
}
+lldb::ScriptInterpreterObjectSP
+ScriptInterpreterPython::MakeScriptObject (void* object)
+{
+ return lldb::ScriptInterpreterObjectSP(new ScriptInterpreterPythonObject(object));
+}
+
ScriptInterpreterPython::SynchronicityHandler::SynchronicityHandler (lldb::DebuggerSP debugger_sp,
ScriptedCommandSynchronicity synchro) :
m_debugger_sp(debugger_sp),
@@ -1914,29 +2020,19 @@ ScriptInterpreterPython::GetDocumentationForItem(const char* item)
}
void
-ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback python_swig_init_callback,
- SWIGBreakpointCallbackFunction python_swig_breakpoint_callback,
- SWIGPythonTypeScriptCallbackFunction python_swig_typescript_callback,
- SWIGPythonCreateSyntheticProvider python_swig_synthetic_script,
- SWIGPythonCalculateNumChildren python_swig_calc_children,
- SWIGPythonGetChildAtIndex python_swig_get_child_index,
- SWIGPythonGetIndexOfChildWithName python_swig_get_index_child,
- SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalue,
- SWIGPythonUpdateSynthProviderInstance python_swig_update_provider,
- SWIGPythonCallCommand python_swig_call_command,
- SWIGPythonCallModuleInit python_swig_call_mod_init)
+ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback python_swig_init_callback)
{
g_swig_init_callback = python_swig_init_callback;
- g_swig_breakpoint_callback = python_swig_breakpoint_callback;
- g_swig_typescript_callback = python_swig_typescript_callback;
- g_swig_synthetic_script = python_swig_synthetic_script;
- g_swig_calc_children = python_swig_calc_children;
- g_swig_get_child_index = python_swig_get_child_index;
- g_swig_get_index_child = python_swig_get_index_child;
- g_swig_cast_to_sbvalue = python_swig_cast_to_sbvalue;
- g_swig_update_provider = python_swig_update_provider;
- g_swig_call_command = python_swig_call_command;
- g_swig_call_module_init = python_swig_call_mod_init;
+ g_swig_breakpoint_callback = LLDBSwigPythonBreakpointCallbackFunction;
+ g_swig_typescript_callback = LLDBSwigPythonCallTypeScript;
+ g_swig_synthetic_script = LLDBSwigPythonCreateSyntheticProvider;
+ g_swig_calc_children = LLDBSwigPython_CalculateNumChildren;
+ g_swig_get_child_index = LLDBSwigPython_GetChildAtIndex;
+ g_swig_get_index_child = LLDBSwigPython_GetIndexOfChildWithName;
+ g_swig_cast_to_sbvalue = LLDBSWIGPython_CastPyObjectToSBValue;
+ g_swig_update_provider = LLDBSwigPython_UpdateSynthProviderInstance;
+ g_swig_call_command = LLDBSwigPythonCallCommand;
+ g_swig_call_module_init = LLDBSwigPythonCallModuleInit;
}
void
OpenPOWER on IntegriCloud