diff options
Diffstat (limited to 'lldb/scripts/Python')
-rw-r--r-- | lldb/scripts/Python/python-typemaps.swig | 110 | ||||
-rw-r--r-- | lldb/scripts/Python/python-wrapper.swig | 527 |
2 files changed, 637 insertions, 0 deletions
diff --git a/lldb/scripts/Python/python-typemaps.swig b/lldb/scripts/Python/python-typemaps.swig new file mode 100644 index 00000000000..5fbe161aa4c --- /dev/null +++ b/lldb/scripts/Python/python-typemaps.swig @@ -0,0 +1,110 @@ +/* Typemap definitions, to allow SWIG to properly handle 'char**' data types. */ + +%typemap(in) char ** { + /* Check if is a list */ + if (PyList_Check($input)) { + int size = PyList_Size($input); + int i = 0; + $1 = (char **) malloc((size+1) * sizeof(char*)); + for (i = 0; i < size; i++) { + PyObject *o = PyList_GetItem($input,i); + if (PyString_Check(o)) + $1[i] = PyString_AsString(o); + else { + PyErr_SetString(PyExc_TypeError,"list must contain strings"); + free($1); + return NULL; + } + } + $1[i] = 0; + } else if ($input == Py_None) { + $1 = NULL; + } else { + PyErr_SetString(PyExc_TypeError,"not a list"); + return NULL; + } +} + +%typemap(freearg) char** { + free((char *) $1); +} + +%typemap(out) char** { + int len; + int i; + len = 0; + while ($1[len]) len++; + $result = PyList_New(len); + for (i = 0; i < len; i++) { + PyList_SetItem($result, i, PyString_FromString($1[i])); + } +} + +/* Typemap definitions to allow SWIG to properly handle char buffer. */ + +// typemap for a char buffer +// See also SBThread::GetStopDescription. +%typemap(in) (char *dst, size_t dst_len) { + if (!PyInt_Check($input)) { + PyErr_SetString(PyExc_ValueError, "Expecting an integer"); + return NULL; + } + $2 = PyInt_AsLong($input); + if ($2 <= 0) { + PyErr_SetString(PyExc_ValueError, "Positive integer expected"); + return NULL; + } + $1 = (char *) malloc($2); +} + +// Return the char buffer. Discarding any previous return result +// See also SBThread::GetStopDescription. +%typemap(argout) (char *dst, size_t dst_len) { + Py_XDECREF($result); /* Blow away any previous result */ + $result = PyString_FromStringAndSize(($1),result); + free($1); +} + + +// typemap for an outgoing buffer +// See also SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len). +%typemap(in) (const char *cstr, uint32_t cstr_len) { + if (!PyString_Check($input)) { + PyErr_SetString(PyExc_ValueError, "Expecting a string"); + return NULL; + } + $1 = (char *) PyString_AsString($input); + $2 = PyString_Size($input); +} +// And SBProcess::WriteMemory. +%typemap(in) (const void *buf, size_t size) { + if (!PyString_Check($input)) { + PyErr_SetString(PyExc_ValueError, "Expecting a string"); + return NULL; + } + $1 = (void *) PyString_AsString($input); + $2 = PyString_Size($input); +} + +// typemap for an incoming buffer +// See also SBProcess::ReadMemory. +%typemap(in) (void *buf, size_t size) { + if (!PyInt_Check($input)) { + PyErr_SetString(PyExc_ValueError, "Expecting an integer"); + return NULL; + } + $2 = PyInt_AsLong($input); + if ($2 <= 0) { + PyErr_SetString(PyExc_ValueError, "Positive integer expected"); + return NULL; + } + $1 = (void *) malloc($2); +} + +// Return the buffer. Discarding any previous return result +// See also SBProcess::ReadMemory. +%typemap(argout) (void *buf, size_t size) { + Py_XDECREF($result); /* Blow away any previous result */ + $result = PyString_FromStringAndSize(static_cast<const char*>($1),result); + free($1); +} diff --git a/lldb/scripts/Python/python-wrapper.swig b/lldb/scripts/Python/python-wrapper.swig new file mode 100644 index 00000000000..28fd1006913 --- /dev/null +++ b/lldb/scripts/Python/python-wrapper.swig @@ -0,0 +1,527 @@ +%wrapper %{ + +// This function is called by lldb_private::ScriptInterpreterPython::BreakpointCallbackFunction(...) +// and is used when a script command is attached to a breakpoint for execution. + +SWIGEXPORT bool +LLDBSwigPythonBreakpointCallbackFunction +( + const char *python_function_name, + const char *session_dictionary_name, + const lldb::StackFrameSP& frame_sp, + const lldb::BreakpointLocationSP& bp_loc_sp +) +{ + lldb::SBFrame sb_frame (frame_sp); + lldb::SBBreakpointLocation sb_bp_loc(bp_loc_sp); + + bool stop_at_breakpoint = true; + PyObject *Frame_PyObj = SWIG_NewPointerObj((void *) &sb_frame, SWIGTYPE_p_lldb__SBFrame, 0); + PyObject *Bp_Loc_PyObj = SWIG_NewPointerObj ((void *) &sb_bp_loc, SWIGTYPE_p_lldb__SBBreakpointLocation, 0); + + if (Frame_PyObj == NULL || Bp_Loc_PyObj == NULL) + return stop_at_breakpoint; + + if (!python_function_name || !session_dictionary_name) + return stop_at_breakpoint; + + PyObject *pmodule, *main_dict, *session_dict, *pfunc; + PyObject *pargs, *pvalue; + + pmodule = PyImport_AddModule ("__main__"); + if (pmodule != NULL) + { + main_dict = PyModule_GetDict (pmodule); + if (main_dict != NULL) + { + PyObject *key, *value; + Py_ssize_t pos = 0; + + // Find the current session's dictionary in the main module's dictionary. + + if (PyDict_Check (main_dict)) + { + session_dict = NULL; + 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), session_dictionary_name) == 0) + { + session_dict = value; + break; + } + } + } + + if (!session_dict || !PyDict_Check (session_dict)) + return stop_at_breakpoint; + + // Find the function we need to call in the current session's dictionary. + + pos = 0; + pfunc = NULL; + while (PyDict_Next (session_dict, &pos, &key, &value)) + { + if (PyString_Check (key)) + { + // 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), python_function_name) == 0) + { + pfunc = value; + break; + } + } + } + + // Set up the arguments and call the function. + + if (pfunc && PyCallable_Check (pfunc)) + { + pargs = PyTuple_New (3); + if (pargs == NULL) + { + if (PyErr_Occurred()) + PyErr_Clear(); + return stop_at_breakpoint; + } + + PyTuple_SetItem (pargs, 0, Frame_PyObj); // This "steals" a reference to Frame_PyObj + PyTuple_SetItem (pargs, 1, Bp_Loc_PyObj); // This "steals" a reference to Bp_Loc_PyObj + PyTuple_SetItem (pargs, 2, session_dict); // This "steals" a reference to session_dict + pvalue = PyObject_CallObject (pfunc, pargs); + Py_DECREF (pargs); + + if (pvalue != NULL) + { + Py_DECREF (pvalue); + } + else if (PyErr_Occurred ()) + { + PyErr_Clear(); + } + Py_INCREF (session_dict); + } + else if (PyErr_Occurred()) + { + PyErr_Clear(); + } + } + else if (PyErr_Occurred()) + { + PyErr_Clear(); + } + } + else if (PyErr_Occurred ()) + { + PyErr_Clear (); + } + return stop_at_breakpoint; +} + +SWIGEXPORT std::string +LLDBSwigPythonCallTypeScript +( + const char *python_function_name, + const char *session_dictionary_name, + const lldb::ValueObjectSP& valobj_sp +) +{ + lldb::SBValue sb_value (valobj_sp); + + std::string retval = ""; + + PyObject *ValObj_PyObj = SWIG_NewPointerObj((void *) &valobj_sp, SWIGTYPE_p_lldb__SBValue, 0); + + if (ValObj_PyObj == NULL) + return retval; + + if (!python_function_name || !session_dictionary_name) + return retval; + + PyObject *pmodule, *main_dict, *session_dict, *pfunc; + PyObject *pargs, *pvalue; + + pmodule = PyImport_AddModule ("__main__"); + if (pmodule != NULL) + { + main_dict = PyModule_GetDict (pmodule); + if (main_dict != NULL) + { + PyObject *key, *value; + Py_ssize_t pos = 0; + + // Find the current session's dictionary in the main module's dictionary. + + if (PyDict_Check (main_dict)) + { + session_dict = NULL; + 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), session_dictionary_name) == 0) + { + session_dict = value; + break; + } + } + } + + if (!session_dict || !PyDict_Check (session_dict)) + return retval; + + // Find the function we need to call in the current session's dictionary. + + pos = 0; + pfunc = NULL; + while (PyDict_Next (session_dict, &pos, &key, &value)) + { + if (PyString_Check (key)) + { + // 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), python_function_name) == 0) + { + pfunc = value; + break; + } + } + } + + // Set up the arguments and call the function. + + if (pfunc && PyCallable_Check (pfunc)) + { + pargs = PyTuple_New (2); + if (pargs == NULL) + { + if (PyErr_Occurred()) + PyErr_Clear(); + return retval; + } + + PyTuple_SetItem (pargs, 0, ValObj_PyObj); // This "steals" a reference to ValObj_PyObj + PyTuple_SetItem (pargs, 1, session_dict); // This "steals" a reference to session_dict + pvalue = PyObject_CallObject (pfunc, pargs); + Py_DECREF (pargs); + + if (pvalue != NULL) + { + if (pvalue != Py_None) + retval = std::string(PyString_AsString(pvalue)); + else + retval = "None"; + Py_DECREF (pvalue); + } + else if (PyErr_Occurred ()) + { + PyErr_Print(); + PyErr_Clear(); + } + Py_INCREF (session_dict); + } + else if (PyErr_Occurred()) + { + PyErr_Print(); + PyErr_Clear(); + } + } + else if (PyErr_Occurred()) + { + PyErr_Print(); + PyErr_Clear(); + } + } + else if (PyErr_Occurred ()) + { + PyErr_Print(); + PyErr_Clear (); + } + return retval; +} + +SWIGEXPORT void* +LLDBSwigPythonCreateSyntheticProvider +( + const std::string python_class_name, + const char *session_dictionary_name, + const lldb::ValueObjectSP& valobj_sp +) +{ + PyObject* retval = NULL; + + if (python_class_name.empty() || !session_dictionary_name) + Py_RETURN_NONE; + + lldb::ValueObjectSP* valobj_sp_ptr = new lldb::ValueObjectSP(valobj_sp); + + PyObject *ValObj_PyObj = SWIG_NewPointerObj((void *) valobj_sp_ptr, SWIGTYPE_p_lldb__SBValue, SWIG_POINTER_OWN); + + if (ValObj_PyObj == NULL) + Py_RETURN_NONE; + + const char* python_function_name = python_class_name.c_str(); + + PyObject *pmodule, *main_dict, *session_dict, *pfunc; + PyObject *pvalue; + + pmodule = PyImport_AddModule ("__main__"); + if (pmodule != NULL) + { + main_dict = PyModule_GetDict (pmodule); + if (main_dict != NULL) + { + PyObject *key, *value; + Py_ssize_t pos = 0; + + // Find the current session's dictionary in the main module's dictionary. + + if (PyDict_Check (main_dict)) + { + session_dict = NULL; + 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), session_dictionary_name) == 0) + { + session_dict = value; + break; + } + } + } + + if (!session_dict || !PyDict_Check (session_dict)) + return retval; + + // Find the function we need to call in the current session's dictionary. + + pos = 0; + pfunc = NULL; + while (PyDict_Next (session_dict, &pos, &key, &value)) + { + if (PyString_Check (key)) + { + // 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), python_function_name) == 0) + { + pfunc = value; + break; + } + } + } + + // Set up the arguments and call the function. + + if (pfunc && PyCallable_Check (pfunc)) + { + PyObject *argList = Py_BuildValue("SS", ValObj_PyObj, session_dict); + + if (PyErr_Occurred ()) + { + PyErr_Print(); + PyErr_Clear(); + return retval; + } + + if (argList == NULL) + { + return retval; + } + + Py_INCREF(ValObj_PyObj); + + pvalue = PyObject_CallObject(pfunc, argList); + + Py_DECREF(argList); + + if (pvalue != NULL) + { + if (pvalue != Py_None) + retval = pvalue; + else + { + retval = Py_None; + Py_INCREF(retval); + } + } + else if (PyErr_Occurred ()) + { + PyErr_Print(); + PyErr_Clear(); + } + Py_INCREF (session_dict); + } + else if (PyErr_Occurred()) + { + PyErr_Print(); + PyErr_Clear(); + } + } + else if (PyErr_Occurred()) + { + PyErr_Print(); + PyErr_Clear(); + } + } + else if (PyErr_Occurred ()) + { + PyErr_Print(); + PyErr_Clear (); + } + if (retval) + return retval; + else + Py_RETURN_NONE; +} + +/* +these four calls below are meant to support +Python-based synthetic children providers +they essentially mimic the four pure virtual +method calls provided by the frontend class +*/ + +SWIGEXPORT uint32_t +LLDBSwigPython_CalculateNumChildren +( + PyObject *implementor +) +{ + + static char callee_name[] = "num_children"; + + if (implementor == NULL || implementor == Py_None) + return 0; + PyObject* py_return = PyObject_CallMethod(implementor, callee_name, NULL); + if (PyErr_Occurred()) + { + PyErr_Print(); + PyErr_Clear(); + } + + if (py_return == NULL || py_return == Py_None) + { + Py_XDECREF(py_return); + return UINT32_MAX; + } + long retval = PyInt_AsLong(py_return); + Py_DECREF(py_return); + if (retval >= 0) + return (uint32_t)retval; + if (PyErr_Occurred()) + { + PyErr_Print(); + PyErr_Clear(); + } + return 0; +} + +SWIGEXPORT PyObject* +LLDBSwigPython_GetChildAtIndex +( + PyObject *implementor, + uint32_t idx +) +{ + + static char callee_name[] = "get_child_at_index"; + static char param_format[] = "i"; + + if (implementor == NULL || implementor == Py_None) + return NULL; + PyObject* py_return = PyObject_CallMethod(implementor, callee_name, param_format, idx); + if (PyErr_Occurred()) + { + PyErr_Print(); + PyErr_Clear(); + } + + if (py_return == NULL || py_return == Py_None) + { + Py_XDECREF(py_return); + return NULL; + } + + lldb::SBValue* sbvalue_ptr = NULL; + + if (SWIG_ConvertPtr(py_return, (void**)&sbvalue_ptr, SWIGTYPE_p_lldb__SBValue, 0) == -1) + { + Py_DECREF(py_return); + return NULL; + } + + if (sbvalue_ptr == NULL) + return NULL; + + return py_return; +} + +SWIGEXPORT int +LLDBSwigPython_GetIndexOfChildWithName +( + PyObject *implementor, + const char* child_name +) +{ + static char callee_name[] = "get_child_index"; + static char param_format[] = "s"; + + if (implementor == NULL || implementor == Py_None) + return 0; + PyObject* py_return = PyObject_CallMethod(implementor, callee_name, param_format, child_name); + if (PyErr_Occurred()) + { + PyErr_Print(); + PyErr_Clear(); + } + + if (py_return == NULL || py_return == Py_None) + { + Py_XDECREF(py_return); + return UINT32_MAX; + } + long retval = PyInt_AsLong(py_return); + Py_DECREF(py_return); + if (retval >= 0) + return (uint32_t)retval; + if (PyErr_Occurred()) + { + PyErr_Print(); + PyErr_Clear(); + } + return 0; +} + +SWIGEXPORT lldb::SBValue* +LLDBSWIGPython_CastPyObjectToSBValue +( + PyObject* data +) +{ + lldb::SBValue* sb_ptr = NULL; + + int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBValue, 0); + + if (valid_cast == -1) + return NULL; + + return sb_ptr; +} + +%} |