[Lldb-commits] [lldb] r252906 - Begin converting uses of PyCallable to PythonCallable.

Zachary Turner via lldb-commits lldb-commits at lists.llvm.org
Thu Nov 12 08:23:17 PST 2015


Author: zturner
Date: Thu Nov 12 10:23:16 2015
New Revision: 252906

URL: http://llvm.org/viewvc/llvm-project?rev=252906&view=rev
Log:
Begin converting uses of PyCallable to PythonCallable.

PyCallable is a class that exists solely within the swig wrapper
code.  PythonCallable is a more generic implementation of the same
idea that can be used by any Python-related interop code, and lives
in PythonDataObjects.h

The CL is mostly mechanical, and it doesn't cover every possible
user of PyCallable, because I want to minimize the impact of this
change (as well as making it easier to figure out what went wrong
in case this causes a failure).  I plan to finish up the rest of
the changes in a subsequent patch, culminating in the removal of
PyCallable entirely.

Modified:
    lldb/trunk/scripts/Python/python-wrapper.swig
    lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
    lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h

Modified: lldb/trunk/scripts/Python/python-wrapper.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-wrapper.swig?rev=252906&r1=252905&r2=252906&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/python-wrapper.swig (original)
+++ lldb/trunk/scripts/Python/python-wrapper.swig Thu Nov 12 10:23:16 2015
@@ -191,21 +191,19 @@ LLDBSwigPythonBreakpointCallbackFunction
     bool stop_at_breakpoint = true;
 
     PyErr_Cleaner py_err_cleaner(true);
-    PythonDictionary dict = PythonModule::MainModule().ResolveName(session_dictionary_name).AsType<PythonDictionary>();
+    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
+    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
 
-    PyCallable pfunc = PyCallable::FindWithFunctionName(python_function_name,dict.get());
-
-    if (!pfunc)
+    if (!pfunc.IsAllocated())
         return stop_at_breakpoint;
 
-    PyObject* pvalue = NULL;
-    pvalue = pfunc(sb_frame, sb_bp_loc, dict.get());
+    PythonObject frame_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_frame));
+    PythonObject bp_loc_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_bp_loc));
+    PythonObject result = pfunc(frame_arg, bp_loc_arg, dict);
 
-    if (pvalue == Py_False)
+    if (result.get() == Py_False)
         stop_at_breakpoint = false;
 
-    Py_XDECREF (pvalue);
-
     return stop_at_breakpoint;
 }
 
@@ -229,21 +227,19 @@ LLDBSwigPythonWatchpointCallbackFunction
 
     PyErr_Cleaner py_err_cleaner(true);
 
-    PythonDictionary dict = PythonModule::MainModule().ResolveName(session_dictionary_name).AsType<PythonDictionary>();
-
-    PyCallable pfunc = PyCallable::FindWithFunctionName(python_function_name,dict.get());
+    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
+    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
 
-    if (!pfunc)
+    if (!pfunc.IsAllocated())
         return stop_at_watchpoint;
 
-    PyObject* pvalue = NULL;
-    pvalue = pfunc(sb_frame, sb_wp, dict.get());
+    PythonObject frame_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_frame));
+    PythonObject wp_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_wp));
+    PythonObject result = pfunc(frame_arg, wp_arg, dict);
 
-    if (pvalue == Py_False)
+    if (result.get() == Py_False)
         stop_at_watchpoint = false;
 
-    Py_XDECREF (pvalue);
-
     return stop_at_watchpoint;
 }
 
@@ -294,7 +290,7 @@ LLDBSwigPythonCallTypeScript
     if (!python_function_name || !session_dictionary)
         return false;
 
-    PyObject *pfunc_impl = NULL, *pvalue = NULL;
+    PyObject *pfunc_impl = nullptr;
 
     if (pyfunct_wrapper && *pyfunct_wrapper && PyFunction_Check (*pyfunct_wrapper))
     {
@@ -314,33 +310,33 @@ LLDBSwigPythonCallTypeScript
 
     PyErr_Cleaner pyerr_cleanup(true);  // show Python errors
 
-    if (!pfunc_impl)
+    PythonCallable pfunc(PyRefType::Borrowed, pfunc_impl);
+
+    if (!pfunc.IsAllocated())
     {
-        pfunc_impl = PythonObject::ResolveNameWithDictionary(python_function_name, dict).release();
-        if (!pfunc_impl || !PyCallable_Check (pfunc_impl))
+        pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
+        if (!pfunc.IsAllocated())
             return false;
-        else
+
+        if (pyfunct_wrapper)
         {
-            if (pyfunct_wrapper)
-                *pyfunct_wrapper = pfunc_impl;
+            *pyfunct_wrapper = pfunc.get();
+            Py_XINCREF(pfunc.get());
         }
     }
 
-    PyCallable pfunc = PyCallable::FindWithPythonObject(pfunc_impl);
-
-    if (!pfunc)
-        return false;
-
+    PythonObject result;
+    auto argc = pfunc.GetNumArguments();
     // if the third argument is supported, or varargs are allowed
-    PyCallable::argc argc = pfunc.GetNumArguments();
-    if (argc.num_args == 3 || argc.varargs == true)
-        pvalue = pfunc(sb_value,dict.get(),sb_options);
+    PythonObject value_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_value));
+    PythonObject options_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_options));
+    if (argc.count == 3 || argc.has_varargs)
+        result = pfunc(value_arg,dict,options_arg);
     else
-        pvalue = pfunc(sb_value,dict.get());
+        result = pfunc(value_arg,dict);
 
-    PyObjectToString(pvalue,retval);
+    PyObjectToString(result.get(), retval);
 
-    Py_XDECREF (pvalue);
     return true;
 }
 
@@ -353,38 +349,33 @@ LLDBSwigPythonCreateSyntheticProvider
 )
 {
     using namespace lldb_private;
-    PyObject* retval = NULL;
 
     if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
         Py_RETURN_NONE;
 
+    PyErr_Cleaner py_err_cleaner(true);
+
+    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
+    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name,dict);
+
+    if (!pfunc.IsAllocated())
+        Py_RETURN_NONE;
+
     // I do not want the SBValue to be deallocated when going out of scope because python
     // has ownership of it and will manage memory for this object by itself
     lldb::SBValue *sb_value = new lldb::SBValue(valobj_sp);
     sb_value->SetPreferSyntheticValue(false);
-    PyObject *ValObj_PyObj = SBTypeToSWIGWrapper(sb_value);
 
-    if (ValObj_PyObj == NULL)
+    PythonObject val_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_value));
+    if (!val_arg.IsAllocated())
         Py_RETURN_NONE;
 
-    PyErr_Cleaner py_err_cleaner(true);
-
-    PythonDictionary dict = PythonModule::MainModule().ResolveName(session_dictionary_name).AsType<PythonDictionary>();
-    PyCallable pfunc = PyCallable::FindWithFunctionName(python_class_name,dict.get());
+    PythonObject result = pfunc(val_arg, dict);
 
-    if (!pfunc)
-        return retval;
+    if (result.IsAllocated())
+        return result.release();
 
-    Py_INCREF(ValObj_PyObj);
-
-    retval = pfunc(sb_value, dict.get());
-
-    Py_XINCREF(retval);
-
-    if (retval)
-        return retval;
-    else
-        Py_RETURN_NONE;
+    Py_RETURN_NONE;
 }
 
 SWIGEXPORT void*
@@ -396,28 +387,25 @@ LLDBSwigPythonCreateCommandObject
 )
 {
     using namespace lldb_private;
-    PyObject* retval = NULL;
 
     if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
         Py_RETURN_NONE;
 
-    lldb::SBDebugger debugger_sb(debugger_sp);
-
     PyErr_Cleaner py_err_cleaner(true);
-    PythonDictionary dict = PythonModule::MainModule().ResolveName(session_dictionary_name).AsType<PythonDictionary>();
-    PyCallable pfunc = PyCallable::FindWithFunctionName(python_class_name,dict.get());
+    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
+    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
 
-    if (!pfunc)
-        return retval;
+    if (!pfunc.IsAllocated())
+        return nullptr;
 
-    retval = pfunc(debugger_sb, dict.get());
+    lldb::SBDebugger debugger_sb(debugger_sp);
+    PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb));
+    PythonObject result = pfunc(debugger_arg, dict);
 
-    Py_XINCREF(retval);
+    if (result.IsAllocated())
+        return result.release();
 
-    if (retval)
-        return retval;
-    else
-        Py_RETURN_NONE;
+    Py_RETURN_NONE;
 }
 
 SWIGEXPORT void*
@@ -429,7 +417,6 @@ LLDBSwigPythonCreateScriptedThreadPlan
 )
 {
     using namespace lldb_private;
-    PyObject* retval = NULL;
 
     if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
         Py_RETURN_NONE;
@@ -438,32 +425,26 @@ LLDBSwigPythonCreateScriptedThreadPlan
     // has ownership of it and will manage memory for this object by itself
     lldb::SBThreadPlan *tp_value = new lldb::SBThreadPlan(thread_plan_sp);
 
-    PyObject *ThreadPlan_PyObj = SBTypeToSWIGWrapper(tp_value);
-
-    if (ThreadPlan_PyObj == NULL)
-        Py_RETURN_NONE;
-
     PyErr_Cleaner py_err_cleaner(true);
 
-    PythonDictionary dict = PythonModule::MainModule().ResolveName(session_dictionary_name).AsType<PythonDictionary>();
-    PyCallable pfunc = PyCallable::FindWithFunctionName(python_class_name, dict.get());
+    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
+    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
 
-    if (!pfunc)
-        return retval;
+    if (!pfunc.IsAllocated())
+        return nullptr;
 
-    Py_INCREF(ThreadPlan_PyObj);
+    PythonObject tp_arg(PyRefType::Owned, SBTypeToSWIGWrapper(tp_value));
 
-    retval = pfunc(tp_value, dict.get());
+    if (!tp_arg.IsAllocated())
+        Py_RETURN_NONE;
 
+    PythonObject result = pfunc(tp_arg, dict);
     // FIXME: At this point we should check that the class we found supports all the methods
     // that we need.
 
-    Py_XINCREF(retval);
-
-    if (retval)
-        return retval;
-    else
-        Py_RETURN_NONE;
+    if (result.IsAllocated())
+        return result.release();
+    Py_RETURN_NONE;
 }
 
 SWIGEXPORT bool
@@ -475,74 +456,64 @@ LLDBSWIGPythonCallThreadPlan
     bool &got_error
 )
 {
-    bool ret_val = false;
-    got_error = false;
+    using namespace lldb_private;
 
+    got_error = false;
 
     PyErr_Cleaner py_err_cleaner(false);
+    PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
+    auto pfunc = self.ResolveName<PythonCallable>(method_name);
 
-    PyCallable pfunc = PyCallable::FindWithMemberFunction((PyObject *) implementor, method_name);
-
-    if (!pfunc)
-    {
-        return ret_val;
-    }
-
-    PyObject* py_return = Py_None;
+    if (!pfunc.IsAllocated())
+        return false;
 
-    if (event != NULL)
+    PythonObject result;
+    if (event != nullptr)
     {
         lldb::SBEvent sb_event(event);
-
-        PyObject *py_obj_event = SBTypeToSWIGWrapper(sb_event);
-
-        py_return = pfunc(py_obj_event);
+        PythonObject event_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_event));
+        result = pfunc(event_arg);
     }
     else
-    {
-        py_return = pfunc();
-    }
+        result = pfunc();
 
     if (PyErr_Occurred())
     {
         got_error = true;
         printf ("Return value was neither false nor true for call to %s.\n", method_name);
         PyErr_Print();
-    }
-    else
-    {
-        if (py_return == Py_True)
-            ret_val = true;
-        else if (py_return == Py_False)
-            ret_val = false;
-        else
-        {
-            // Somebody returned the wrong thing...
-            got_error = true;
-            printf ("Wrong return value type for call to %s.\n", method_name);
-        }
+        return false;
     }
 
-    Py_XDECREF(py_return);
+    if (result.get() == Py_True)
+        return true;
+    else if (result.get() == Py_False)
+        return false;
 
-    return ret_val;
+    // Somebody returned the wrong thing...
+    got_error = true;
+    printf ("Wrong return value type for call to %s.\n", method_name);
+    return false;
 }
 
 // wrapper that calls an optional instance member of an object taking no arguments
 static PyObject*
 LLDBSwigPython_CallOptionalMember
 (
-    PyObject* self,
+    PyObject* implementor,
     char* callee_name,
     PyObject* ret_if_not_found = Py_None,
     bool* was_found = NULL
 )
 {
+    using namespace lldb_private;
+
     PyErr_Cleaner py_err_cleaner(false);
 
-    PyCallable pfunc = PyCallable::FindWithMemberFunction(self,callee_name);
+    PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
+    auto pfunc = self.ResolveName<PythonCallable>(callee_name);
 
-    if (!pfunc)
+    if (!pfunc.IsAllocated())
     {
         if (was_found)
             *was_found = false;
@@ -553,8 +524,8 @@ LLDBSwigPython_CallOptionalMember
     if (was_found)
         *was_found = true;
 
-    PyObject* py_return = pfunc();
-    return py_return;
+    PythonObject result = pfunc();
+    return result.release();
 }
 
 SWIGEXPORT size_t
@@ -564,47 +535,29 @@ LLDBSwigPython_CalculateNumChildren
     uint32_t max
 )
 {
-    size_t ret_val = 0;
-    bool int_match = false;
+    using namespace lldb_private;
 
-    PyCallable pfunc = PyCallable::FindWithMemberFunction(implementor, "num_children");
+    PythonObject self(PyRefType::Borrowed, implementor);
+    auto pfunc = self.ResolveName<PythonCallable>("num_children");
 
-    if (!pfunc)
-        return ret_val;
+    if (!pfunc.IsAllocated())
+        return 0;
 
-    PyObject* py_return = NULL;
+    PythonObject result;
     auto argc = pfunc.GetNumArguments();
-    if (argc.num_args == 1)
-        py_return = pfunc();
-    else if (argc.num_args == 2)
-        py_return = pfunc(max);
-
-    if (!py_return)
-        return ret_val;
-
-    // PyInt_* are not available for Python 3 and above.
-#if PY_MAJOR_VERSION < 3
-    if (PyInt_Check (py_return))
-    {
-        int_match = true;
-        ret_val = static_cast<size_t> (PyInt_AsLong (py_return));
-    }
-#endif
-
-    // We want to check for PyLong only if the return value did not
-    // match PyInt. This is because we do not want to call PyLong_Check if
-    // PyInt_Check returns true but PyInt_AsLong generates an error.
-    if (!int_match && PyLong_Check (py_return))
-    {
-#if PY_MAJOR_VERSION < 3
-        ret_val = static_cast<size_t> (PyLong_AsUnsignedLong (py_return));
-#else
-        // PyLong_AsSize_t is available only for Python 3 and above.
-        ret_val = PyLong_AsSize_t (py_return);
-#endif
-    }
+    if (argc.count == 1)
+        result = pfunc();
+    else if (argc.count == 2)
+        result = pfunc(PythonInteger(max));
+
+    if (!result.IsAllocated())
+        return 0;
+
+    PythonInteger int_result = result.AsType<PythonInteger>();
+    if (!int_result.IsAllocated())
+        return 0;
 
-    Py_XDECREF(py_return);
+    size_t ret_val = int_result.GetInteger();
 
     if (PyErr_Occurred())
     {
@@ -612,8 +565,8 @@ LLDBSwigPython_CalculateNumChildren
         PyErr_Clear();
     }
 
-    if (argc.num_args == 1 && ret_val > max)
-        ret_val = max;
+    if (argc.count == 1)
+        ret_val = std::min(ret_val, max);
 
     return ret_val;
 }
@@ -625,34 +578,28 @@ LLDBSwigPython_GetChildAtIndex
     uint32_t idx
 )
 {
+    using namespace lldb_private;
     PyErr_Cleaner py_err_cleaner(true);
 
-    PyCallable pfunc = PyCallable::FindWithMemberFunction(implementor,"get_child_at_index");
+    PythonObject self(PyRefType::Borrowed, implementor);
+    auto pfunc = self.ResolveName<PythonCallable>("get_child_at_index");
 
-    if (!pfunc)
-        return NULL;
+    if (!pfunc.IsAllocated())
+        return nullptr;
 
-    PyObject *py_return = NULL;
-    py_return = pfunc(idx);
+    PythonObject result = pfunc(PythonInteger(idx));
 
-    if (py_return == NULL || py_return == Py_None)
-    {
-        Py_XDECREF(py_return);
-        return NULL;
-    }
-
-    lldb::SBValue* sbvalue_ptr = NULL;
+    if (!result.IsAllocated())
+        return nullptr;
 
-    if (SWIG_ConvertPtr(py_return, (void**)&sbvalue_ptr, SWIGTYPE_p_lldb__SBValue, 0) == -1)
-    {
-        Py_XDECREF(py_return);
-        return NULL;
-    }
+    lldb::SBValue* sbvalue_ptr = nullptr;
+    if (SWIG_ConvertPtr(result.get(), (void**)&sbvalue_ptr, SWIGTYPE_p_lldb__SBValue, 0) == -1)
+        return nullptr;
 
-    if (sbvalue_ptr == NULL)
-        return NULL;
+    if (sbvalue_ptr == nullptr)
+        return nullptr;
 
-    return py_return;
+    return result.release();
 }
 
 SWIGEXPORT int
@@ -662,25 +609,25 @@ LLDBSwigPython_GetIndexOfChildWithName
     const char* child_name
 )
 {
+    using namespace lldb_private;
     PyErr_Cleaner py_err_cleaner(true);
 
-    PyCallable pfunc = PyCallable::FindWithMemberFunction(implementor,"get_child_index");
+    PythonObject self(PyRefType::Borrowed, implementor);
+    auto pfunc = self.ResolveName<PythonCallable>("get_child_index");
 
-    if (!pfunc)
+    if (!pfunc.IsAllocated())
         return UINT32_MAX;
 
-    PyObject *py_return = NULL;
-    py_return = pfunc(child_name);
+    PythonObject result = pfunc(PythonString(child_name));
 
-    if (py_return == NULL || py_return == Py_None)
-    {
-        Py_XDECREF(py_return);
+    if (!result.IsAllocated())
         return UINT32_MAX;
-    }
 
-    long retval = PyInt_AsLong(py_return);
-    Py_XDECREF(py_return);
+    PythonInteger int_result = result.AsType<PythonInteger>();
+    if (!int_result.IsAllocated())
+        return UINT32_MAX;
 
+    int64_t retval = int_result.GetInteger();
     if (retval >= 0)
         return (uint32_t)retval;
 
@@ -812,30 +759,26 @@ LLDBSwigPythonCallCommand
     lldb::SBDebugger debugger_sb(debugger);
     lldb::SBExecutionContext exe_ctx_sb(exe_ctx_ref_sp);
 
-    bool retval = false;
-
     PyErr_Cleaner py_err_cleaner(true);
-    PythonDictionary dict = PythonModule::MainModule().ResolveName(session_dictionary_name).AsType<PythonDictionary>();
-    PyCallable pfunc = PyCallable::FindWithFunctionName(python_function_name,dict.get());
+    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
+    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
 
-    if (!pfunc)
-        return retval;
+    if (!pfunc.IsAllocated())
+        return false;
 
     // pass the pointer-to cmd_retobj_sb or watch the underlying object disappear from under you
     // see comment above for SBCommandReturnObjectReleaser for further details
-    PyObject* pvalue = NULL;
+    auto argc = pfunc.GetNumArguments();
+    PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb));
+    PythonObject exe_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(exe_ctx_sb));
+    PythonObject cmd_retobj_arg(PyRefType::Owned, SBTypeToSWIGWrapper(&cmd_retobj_sb));
 
-    PyCallable::argc argc = pfunc.GetNumArguments();
-    if (argc.num_args == 5 || argc.varargs == true)
-        pvalue = pfunc(debugger_sb, args, exe_ctx_sb, &cmd_retobj_sb, dict.get());
+    if (argc.count == 5 || argc.has_varargs)
+        pfunc(debugger_arg, PythonString(args), exe_ctx_arg, cmd_retobj_arg, dict);
     else
-        pvalue = pfunc(debugger_sb, args, &cmd_retobj_sb, dict.get());
-
-    Py_XDECREF (pvalue);
+        pfunc(debugger_arg, PythonString(args), cmd_retobj_arg, dict);
 
-    retval = true;
-
-    return retval;
+    return true;
 }
 
 SWIGEXPORT bool
@@ -848,7 +791,7 @@ LLDBSwigPythonCallCommandObject
     lldb::ExecutionContextRefSP exe_ctx_ref_sp
 )
 {
-
+    using namespace lldb_private;
     lldb::SBCommandReturnObject cmd_retobj_sb(&cmd_retobj);
     SBCommandReturnObjectReleaser cmd_retobj_sb_releaser(cmd_retobj_sb);
     lldb::SBDebugger debugger_sb(debugger);
@@ -856,18 +799,19 @@ LLDBSwigPythonCallCommandObject
 
     PyErr_Cleaner py_err_cleaner(true);
 
-    PyCallable pfunc = PyCallable::FindWithMemberFunction(implementor,"__call__");
+    PythonObject self(PyRefType::Borrowed, implementor);
+    auto pfunc = self.ResolveName<PythonCallable>("__call__");
 
-    if (!pfunc)
+    if (!pfunc.IsAllocated())
         return false;
 
     // pass the pointer-to cmd_retobj_sb or watch the underlying object disappear from under you
     // see comment above for SBCommandReturnObjectReleaser for further details
-    PyObject* pvalue = NULL;
-
-    pvalue = pfunc(debugger_sb, args, exe_ctx_sb, &cmd_retobj_sb);
+    PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb));
+    PythonObject exe_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(exe_ctx_sb));
+    PythonObject cmd_retobj_arg(PyRefType::Owned, SBTypeToSWIGWrapper(&cmd_retobj_sb));
 
-    Py_XDECREF (pvalue);
+    pfunc(debugger_arg, PythonString(args), exe_ctx_arg, cmd_retobj_arg);
 
     return true;
 }

Modified: lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp?rev=252906&r1=252905&r2=252906&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp (original)
+++ lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp Thu Nov 12 10:23:16 2015
@@ -904,31 +904,35 @@ PythonCallable::Reset(PyRefType type, Py
 }
 
 
-void
-PythonCallable::GetNumArguments(size_t &num_args, bool &has_varargs, bool &has_kwargs) const
+PythonCallable::ArgInfo
+PythonCallable::GetNumArguments() const
 {
-    num_args = 0;
-    has_varargs = false;
-    has_kwargs = false;
+    ArgInfo result = { 0, false, false };
     if (!IsValid())
-        return;
+        return result;
 
     PyObject *py_func_obj = m_py_obj;
     if (PyMethod_Check(py_func_obj))
         py_func_obj = PyMethod_GET_FUNCTION(py_func_obj);
 
     if (!py_func_obj)
-        return;
+        return result;
 
     PyCodeObject* code = (PyCodeObject*)PyFunction_GET_CODE(py_func_obj);
     if (!code)
-        return;
+        return result;
 
-    num_args = code->co_argcount;
-    if (code->co_flags & CO_VARARGS)
-        has_varargs = true;
-    if (code->co_flags & CO_VARKEYWORDS)
-        has_kwargs = true;
+    result.count = code->co_argcount;
+    result.has_varargs = !!(code->co_flags & CO_VARARGS);
+    result.has_kwargs = !!(code->co_flags & CO_VARKEYWORDS);
+    return result;
+}
+
+PythonObject
+PythonCallable::operator ()()
+{
+    return PythonObject(PyRefType::Owned,
+        PyObject_CallObject(m_py_obj, nullptr));
 }
 
 PythonObject

Modified: lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h?rev=252906&r1=252905&r2=252906&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h (original)
+++ lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h Thu Nov 12 10:23:16 2015
@@ -207,9 +207,23 @@ public:
     static PythonObject
     ResolveNameWithDictionary(llvm::StringRef name, PythonDictionary dict);
 
+    template<typename T>
+    static T
+    ResolveNameWithDictionary(llvm::StringRef name, PythonDictionary dict)
+    {
+        return ResolveNameWithDictionary(name, dict).AsType<T>();
+    }
+
     PythonObject
     ResolveName(llvm::StringRef name) const;
 
+    template<typename T>
+    T
+    ResolveName(llvm::StringRef name) const
+    {
+        return ResolveName(name).AsType<T>();
+    }
+
     bool
     HasAttribute(llvm::StringRef attribute) const;
 
@@ -410,6 +424,12 @@ class PythonModule : public PythonObject
 class PythonCallable : public PythonObject
 {
 public:
+    struct ArgInfo {
+        size_t count;
+        bool has_varargs : 1;
+        bool has_kwargs : 1;
+    };
+
     PythonCallable();
     PythonCallable(PyRefType type, PyObject *o);
     PythonCallable(const PythonCallable &dict);
@@ -425,14 +445,24 @@ public:
     void
     Reset(PyRefType type, PyObject *py_obj) override;
 
-    void
-    GetNumArguments(size_t &num_args, bool &has_varargs, bool &has_kwargs) const;
+    ArgInfo
+    GetNumArguments() const;
+
+    PythonObject
+    operator ()();
 
     PythonObject
     operator ()(std::initializer_list<PyObject*> args);
 
     PythonObject
     operator ()(std::initializer_list<PythonObject> args);
+
+    template<typename Arg, typename... Args>
+    PythonObject
+    operator ()(const Arg &arg, Args... args)
+    {
+        return operator()({ arg, args... });
+    }
 };
 
 




More information about the lldb-commits mailing list