Python synthetic children:
- you can now define a Python class as a synthetic children producer for a type
the class must adhere to this "interface":
def __init__(self, valobj, dict):
def get_child_at_index(self, index):
def get_child_index(self, name):
then using type synth add -l className typeName
(e.g. type synth add -l fooSynthProvider foo)
(This is still WIP with lots to be added)
A small test case is available also as reference
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@135865 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Interpreter/CommandObjectScript.cpp b/source/Interpreter/CommandObjectScript.cpp
index 70a4ead..e586497 100644
--- a/source/Interpreter/CommandObjectScript.cpp
+++ b/source/Interpreter/CommandObjectScript.cpp
@@ -13,6 +13,9 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
+
+#include "lldb/Core/Debugger.h"
+
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -54,6 +57,8 @@
result.SetStatus (eReturnStatusFailed);
}
+ Debugger::Formatting::ForceUpdate(); // script might change Python code we use for formatting.. make sure we keep up to date with it
+
if (command == NULL || command[0] == '\0') {
script_interpreter->ExecuteInterpreterLoop ();
result.SetStatus (eReturnStatusSuccessFinishNoResult);
diff --git a/source/Interpreter/ScriptInterpreter.cpp b/source/Interpreter/ScriptInterpreter.cpp
index 294aeec..27c7bad 100644
--- a/source/Interpreter/ScriptInterpreter.cpp
+++ b/source/Interpreter/ScriptInterpreter.cpp
@@ -93,11 +93,21 @@
void
ScriptInterpreter::InitializeInterpreter (SWIGInitCallback python_swig_init_callback,
SWIGBreakpointCallbackFunction python_swig_breakpoint_callback,
- SWIGPythonTypeScriptCallbackFunction python_swig_typescript_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)
{
ScriptInterpreterPython::InitializeInterpreter (python_swig_init_callback,
python_swig_breakpoint_callback,
- python_swig_typescript_callback);
+ python_swig_typescript_callback,
+ python_swig_synthetic_script,
+ python_swig_calc_children,
+ python_swig_get_child_index,
+ python_swig_get_index_child,
+ python_swig_cast_to_sbvalue);
}
void
diff --git a/source/Interpreter/ScriptInterpreterPython.cpp b/source/Interpreter/ScriptInterpreterPython.cpp
index 57a5929..03eadc6 100644
--- a/source/Interpreter/ScriptInterpreterPython.cpp
+++ b/source/Interpreter/ScriptInterpreterPython.cpp
@@ -35,7 +35,11 @@
static ScriptInterpreter::SWIGInitCallback g_swig_init_callback = NULL;
static ScriptInterpreter::SWIGBreakpointCallbackFunction g_swig_breakpoint_callback = NULL;
static ScriptInterpreter::SWIGPythonTypeScriptCallbackFunction g_swig_typescript_callback = NULL;
-
+static ScriptInterpreter::SWIGPythonCreateSyntheticProvider g_swig_synthetic_script = NULL;
+static ScriptInterpreter::SWIGPythonCalculateNumChildren g_swig_calc_children = NULL;
+static ScriptInterpreter::SWIGPythonGetChildAtIndex g_swig_get_child_index = NULL;
+static ScriptInterpreter::SWIGPythonGetIndexOfChildWithName g_swig_get_index_child = NULL;
+static ScriptInterpreter::SWIGPythonCastPyObjectToSBValue g_swig_cast_to_sbvalue = NULL;
static int
_check_and_flush (FILE *stream)
@@ -1245,6 +1249,55 @@
return true;
}
+void*
+ScriptInterpreterPython::CreateSyntheticScriptedProvider (std::string class_name,
+ lldb::ValueObjectSP valobj)
+{
+ if (class_name.empty())
+ return NULL;
+
+ if (!valobj.get())
+ return NULL;
+
+ Target *target = valobj->GetUpdatePoint().GetTarget();
+
+ if (!target)
+ return NULL;
+
+ Debugger &debugger = target->GetDebugger();
+ ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
+ ScriptInterpreterPython *python_interpreter = (ScriptInterpreterPython *) script_interpreter;
+
+ if (!script_interpreter)
+ return NULL;
+
+ void* ret_val;
+
+ FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
+ if (CurrentThreadHasPythonLock())
+ {
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_synthetic_script (class_name,
+ python_interpreter->m_dictionary_name.c_str(),
+ valobj);
+ python_interpreter->LeaveSession ();
+ }
+ else
+ {
+ while (!GetPythonLock (1))
+ fprintf (tmp_fh,
+ "Python interpreter locked on another thread; waiting to acquire lock...\n");
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_synthetic_script (class_name,
+ python_interpreter->m_dictionary_name.c_str(),
+ valobj);
+ python_interpreter->LeaveSession ();
+ ReleasePythonLock ();
+ }
+
+ return ret_val;
+}
+
bool
ScriptInterpreterPython::GenerateTypeScriptFunction (const char* oneliner, StringList &output)
{
@@ -1565,15 +1618,161 @@
return NULL;
}
+uint32_t
+ScriptInterpreterPython::CalculateNumChildren (void *implementor)
+{
+ if (!implementor)
+ return 0;
+
+ if (!g_swig_calc_children)
+ return 0;
+
+ ScriptInterpreterPython *python_interpreter = this;
+
+ uint32_t ret_val = 0;
+
+ FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
+ if (CurrentThreadHasPythonLock())
+ {
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_calc_children (implementor);
+ python_interpreter->LeaveSession ();
+ }
+ else
+ {
+ while (!GetPythonLock (1))
+ fprintf (tmp_fh,
+ "Python interpreter locked on another thread; waiting to acquire lock...\n");
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_calc_children (implementor);
+ python_interpreter->LeaveSession ();
+ ReleasePythonLock ();
+ }
+
+ return ret_val;
+}
+
+void*
+ScriptInterpreterPython::GetChildAtIndex (void *implementor, uint32_t idx)
+{
+ if (!implementor)
+ return 0;
+
+ if (!g_swig_get_child_index)
+ return 0;
+
+ ScriptInterpreterPython *python_interpreter = this;
+
+ void* ret_val = NULL;
+
+ FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
+ if (CurrentThreadHasPythonLock())
+ {
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_get_child_index (implementor,idx);
+ python_interpreter->LeaveSession ();
+ }
+ else
+ {
+ while (!GetPythonLock (1))
+ fprintf (tmp_fh,
+ "Python interpreter locked on another thread; waiting to acquire lock...\n");
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_get_child_index (implementor,idx);
+ python_interpreter->LeaveSession ();
+ ReleasePythonLock ();
+ }
+
+ return ret_val;
+}
+
+int
+ScriptInterpreterPython::GetIndexOfChildWithName (void *implementor, const char* child_name)
+{
+ if (!implementor)
+ return UINT32_MAX;
+
+ if (!g_swig_get_index_child)
+ return UINT32_MAX;
+
+ ScriptInterpreterPython *python_interpreter = this;
+
+ int ret_val = UINT32_MAX;
+
+ FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
+ if (CurrentThreadHasPythonLock())
+ {
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_get_index_child (implementor, child_name);
+ python_interpreter->LeaveSession ();
+ }
+ else
+ {
+ while (!GetPythonLock (1))
+ fprintf (tmp_fh,
+ "Python interpreter locked on another thread; waiting to acquire lock...\n");
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_get_index_child (implementor, child_name);
+ python_interpreter->LeaveSession ();
+ ReleasePythonLock ();
+ }
+
+ return ret_val;
+}
+
+lldb::SBValue*
+ScriptInterpreterPython::CastPyObjectToSBValue (void* data)
+{
+ if (!data)
+ return NULL;
+
+ if (!g_swig_cast_to_sbvalue)
+ return NULL;
+
+ ScriptInterpreterPython *python_interpreter = this;
+
+ lldb::SBValue* ret_val = NULL;
+
+ FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
+ if (CurrentThreadHasPythonLock())
+ {
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_cast_to_sbvalue (data);
+ python_interpreter->LeaveSession ();
+ }
+ else
+ {
+ while (!GetPythonLock (1))
+ fprintf (tmp_fh,
+ "Python interpreter locked on another thread; waiting to acquire lock...\n");
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_cast_to_sbvalue (data);
+ python_interpreter->LeaveSession ();
+ ReleasePythonLock ();
+ }
+
+ return ret_val;
+}
+
void
ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback python_swig_init_callback,
SWIGBreakpointCallbackFunction python_swig_breakpoint_callback,
- SWIGPythonTypeScriptCallbackFunction python_swig_typescript_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)
{
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;
}
void