16498aff2SJonas Devlieghere%header %{
26498aff2SJonas Devlieghere
39d5e37edSPavel Labathclass PyErr_Cleaner {
46498aff2SJonas Devliegherepublic:
59d5e37edSPavel Labath  PyErr_Cleaner(bool print = false) : m_print(print) {}
66498aff2SJonas Devlieghere
79d5e37edSPavel Labath  ~PyErr_Cleaner() {
89d5e37edSPavel Labath    if (PyErr_Occurred()) {
96498aff2SJonas Devlieghere      if (m_print && !PyErr_ExceptionMatches(PyExc_SystemExit))
106498aff2SJonas Devlieghere        PyErr_Print();
116498aff2SJonas Devlieghere      PyErr_Clear();
126498aff2SJonas Devlieghere    }
136498aff2SJonas Devlieghere  }
146498aff2SJonas Devlieghere
156498aff2SJonas Devlieghereprivate:
166498aff2SJonas Devlieghere  bool m_print;
176498aff2SJonas Devlieghere};
186498aff2SJonas Devlieghere
199d5e37edSPavel Labathllvm::Expected<bool> lldb_private::LLDBSwigPythonBreakpointCallbackFunction(
209d5e37edSPavel Labath    const char *python_function_name, const char *session_dictionary_name,
216498aff2SJonas Devlieghere    const lldb::StackFrameSP &frame_sp,
226498aff2SJonas Devlieghere    const lldb::BreakpointLocationSP &bp_loc_sp,
239d5e37edSPavel Labath    const lldb_private::StructuredDataImpl &args_impl) {
246498aff2SJonas Devlieghere  using namespace llvm;
256498aff2SJonas Devlieghere
266498aff2SJonas Devlieghere  lldb::SBBreakpointLocation sb_bp_loc(bp_loc_sp);
276498aff2SJonas Devlieghere
286498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(true);
299d5e37edSPavel Labath  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
309d5e37edSPavel Labath      session_dictionary_name);
319d5e37edSPavel Labath  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
329d5e37edSPavel Labath      python_function_name, dict);
336498aff2SJonas Devlieghere
346498aff2SJonas Devlieghere  unsigned max_positional_args;
356498aff2SJonas Devlieghere  if (auto arg_info = pfunc.GetArgInfo())
366498aff2SJonas Devlieghere    max_positional_args = arg_info.get().max_positional_args;
376498aff2SJonas Devlieghere  else
386498aff2SJonas Devlieghere    return arg_info.takeError();
396498aff2SJonas Devlieghere
407406d236SPavel Labath  PythonObject frame_arg = ToSWIGWrapper(frame_sp);
412efc6892SPavel Labath  PythonObject bp_loc_arg = ToSWIGWrapper(bp_loc_sp);
426498aff2SJonas Devlieghere
432efc6892SPavel Labath  auto result =
442efc6892SPavel Labath      max_positional_args < 4
452efc6892SPavel Labath          ? pfunc.Call(frame_arg, bp_loc_arg, dict)
462efc6892SPavel Labath          : pfunc.Call(frame_arg, bp_loc_arg, ToSWIGWrapper(args_impl), dict);
476498aff2SJonas Devlieghere
486498aff2SJonas Devlieghere  if (!result)
496498aff2SJonas Devlieghere    return result.takeError();
506498aff2SJonas Devlieghere
516498aff2SJonas Devlieghere  // Only False counts as false!
526498aff2SJonas Devlieghere  return result.get().get() != Py_False;
536498aff2SJonas Devlieghere}
546498aff2SJonas Devlieghere
559a14adeaSPavel Labath// resolve a dotted Python name in the form
569a14adeaSPavel Labath// foo.bar.baz.Foobar to an actual Python object
579a14adeaSPavel Labath// if pmodule is NULL, the __main__ module will be used
589a14adeaSPavel Labath// as the starting point for the search
59daf36998SDave Lee
609d5e37edSPavel Labath// This function is called by
619d5e37edSPavel Labath// lldb_private::ScriptInterpreterPython::BreakpointCallbackFunction(...) and is
629d5e37edSPavel Labath// used when a script command is attached to a breakpoint for execution.
639a14adeaSPavel Labath
649d5e37edSPavel Labath// This function is called by
659d5e37edSPavel Labath// lldb_private::ScriptInterpreterPython::WatchpointCallbackFunction(...) and is
669d5e37edSPavel Labath// used when a script command is attached to a watchpoint for execution.
67daf36998SDave Lee
689d5e37edSPavel Labathbool lldb_private::LLDBSwigPythonWatchpointCallbackFunction(
699d5e37edSPavel Labath    const char *python_function_name, const char *session_dictionary_name,
709d5e37edSPavel Labath    const lldb::StackFrameSP &frame_sp, const lldb::WatchpointSP &wp_sp) {
716498aff2SJonas Devlieghere
726498aff2SJonas Devlieghere  bool stop_at_watchpoint = true;
736498aff2SJonas Devlieghere
746498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(true);
756498aff2SJonas Devlieghere
769d5e37edSPavel Labath  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
779d5e37edSPavel Labath      session_dictionary_name);
789d5e37edSPavel Labath  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
799d5e37edSPavel Labath      python_function_name, dict);
806498aff2SJonas Devlieghere
816498aff2SJonas Devlieghere  if (!pfunc.IsAllocated())
826498aff2SJonas Devlieghere    return stop_at_watchpoint;
836498aff2SJonas Devlieghere
842efc6892SPavel Labath  PythonObject result =
852efc6892SPavel Labath      pfunc(ToSWIGWrapper(frame_sp), ToSWIGWrapper(wp_sp), dict);
866498aff2SJonas Devlieghere
876498aff2SJonas Devlieghere  if (result.get() == Py_False)
886498aff2SJonas Devlieghere    stop_at_watchpoint = false;
896498aff2SJonas Devlieghere
906498aff2SJonas Devlieghere  return stop_at_watchpoint;
916498aff2SJonas Devlieghere}
926498aff2SJonas Devlieghere
939d5e37edSPavel Labathbool lldb_private::LLDBSwigPythonCallTypeScript(
949d5e37edSPavel Labath    const char *python_function_name, const void *session_dictionary,
959d5e37edSPavel Labath    const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper,
969d5e37edSPavel Labath    const lldb::TypeSummaryOptionsSP &options_sp, std::string &retval) {
976498aff2SJonas Devlieghere
986498aff2SJonas Devlieghere  retval.clear();
996498aff2SJonas Devlieghere
1006498aff2SJonas Devlieghere  if (!python_function_name || !session_dictionary)
1016498aff2SJonas Devlieghere    return false;
1026498aff2SJonas Devlieghere
1036498aff2SJonas Devlieghere  PyObject *pfunc_impl = nullptr;
1046498aff2SJonas Devlieghere
1059d5e37edSPavel Labath  if (pyfunct_wrapper && *pyfunct_wrapper &&
1069d5e37edSPavel Labath      PyFunction_Check(*pyfunct_wrapper)) {
1076498aff2SJonas Devlieghere    pfunc_impl = (PyObject *)(*pyfunct_wrapper);
1089d5e37edSPavel Labath    if (pfunc_impl->ob_refcnt == 1) {
1096498aff2SJonas Devlieghere      Py_XDECREF(pfunc_impl);
1106498aff2SJonas Devlieghere      pfunc_impl = NULL;
1116498aff2SJonas Devlieghere    }
1126498aff2SJonas Devlieghere  }
1136498aff2SJonas Devlieghere
1146498aff2SJonas Devlieghere  PyObject *py_dict = (PyObject *)session_dictionary;
1156498aff2SJonas Devlieghere  if (!PythonDictionary::Check(py_dict))
1166498aff2SJonas Devlieghere    return true;
1176498aff2SJonas Devlieghere
1186498aff2SJonas Devlieghere  PythonDictionary dict(PyRefType::Borrowed, py_dict);
1196498aff2SJonas Devlieghere
1206498aff2SJonas Devlieghere  PyErr_Cleaner pyerr_cleanup(true); // show Python errors
1216498aff2SJonas Devlieghere
1226498aff2SJonas Devlieghere  PythonCallable pfunc(PyRefType::Borrowed, pfunc_impl);
1236498aff2SJonas Devlieghere
1249d5e37edSPavel Labath  if (!pfunc.IsAllocated()) {
1259d5e37edSPavel Labath    pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
1269d5e37edSPavel Labath        python_function_name, dict);
1276498aff2SJonas Devlieghere    if (!pfunc.IsAllocated())
1286498aff2SJonas Devlieghere      return false;
1296498aff2SJonas Devlieghere
1309d5e37edSPavel Labath    if (pyfunct_wrapper) {
1316498aff2SJonas Devlieghere      *pyfunct_wrapper = pfunc.get();
1326498aff2SJonas Devlieghere      Py_XINCREF(pfunc.get());
1336498aff2SJonas Devlieghere    }
1346498aff2SJonas Devlieghere  }
1356498aff2SJonas Devlieghere
1366498aff2SJonas Devlieghere  PythonObject result;
1376498aff2SJonas Devlieghere  auto argc = pfunc.GetArgInfo();
1386498aff2SJonas Devlieghere  if (!argc) {
1396498aff2SJonas Devlieghere    llvm::consumeError(argc.takeError());
1406498aff2SJonas Devlieghere    return false;
1416498aff2SJonas Devlieghere  }
1426498aff2SJonas Devlieghere
1437f09ab08SPavel Labath  PythonObject value_arg = ToSWIGWrapper(valobj_sp);
1446498aff2SJonas Devlieghere
1456498aff2SJonas Devlieghere  if (argc.get().max_positional_args < 3)
1466498aff2SJonas Devlieghere    result = pfunc(value_arg, dict);
1476498aff2SJonas Devlieghere  else
1482efc6892SPavel Labath    result = pfunc(value_arg, dict, ToSWIGWrapper(*options_sp));
1496498aff2SJonas Devlieghere
1506498aff2SJonas Devlieghere  retval = result.Str().GetString().str();
1516498aff2SJonas Devlieghere
1526498aff2SJonas Devlieghere  return true;
1536498aff2SJonas Devlieghere}
1546498aff2SJonas Devlieghere
155*c154f397SPavel LabathPythonObject lldb_private::LLDBSwigPythonCreateSyntheticProvider(
1569d5e37edSPavel Labath    const char *python_class_name, const char *session_dictionary_name,
1579d5e37edSPavel Labath    const lldb::ValueObjectSP &valobj_sp) {
1589d5e37edSPavel Labath  if (python_class_name == NULL || python_class_name[0] == '\0' ||
1599d5e37edSPavel Labath      !session_dictionary_name)
160*c154f397SPavel Labath    return PythonObject();
1616498aff2SJonas Devlieghere
1626498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(true);
1636498aff2SJonas Devlieghere
1649d5e37edSPavel Labath  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
1659d5e37edSPavel Labath      session_dictionary_name);
1669d5e37edSPavel Labath  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
1679d5e37edSPavel Labath      python_class_name, dict);
1686498aff2SJonas Devlieghere
1696498aff2SJonas Devlieghere  if (!pfunc.IsAllocated())
170*c154f397SPavel Labath    return PythonObject();
1716498aff2SJonas Devlieghere
1727f09ab08SPavel Labath  auto sb_value = std::make_unique<lldb::SBValue>(valobj_sp);
1736498aff2SJonas Devlieghere  sb_value->SetPreferSyntheticValue(false);
1746498aff2SJonas Devlieghere
1757f09ab08SPavel Labath  PythonObject val_arg = ToSWIGWrapper(std::move(sb_value));
1766498aff2SJonas Devlieghere  if (!val_arg.IsAllocated())
177*c154f397SPavel Labath    return PythonObject();
1786498aff2SJonas Devlieghere
1796498aff2SJonas Devlieghere  PythonObject result = pfunc(val_arg, dict);
1806498aff2SJonas Devlieghere
1816498aff2SJonas Devlieghere  if (result.IsAllocated())
182*c154f397SPavel Labath    return result;
1836498aff2SJonas Devlieghere
184*c154f397SPavel Labath  return PythonObject();
1856498aff2SJonas Devlieghere}
1866498aff2SJonas Devlieghere
187*c154f397SPavel LabathPythonObject lldb_private::LLDBSwigPythonCreateCommandObject(
1889d5e37edSPavel Labath    const char *python_class_name, const char *session_dictionary_name,
1897406d236SPavel Labath    lldb::DebuggerSP debugger_sp) {
1909d5e37edSPavel Labath  if (python_class_name == NULL || python_class_name[0] == '\0' ||
1919d5e37edSPavel Labath      !session_dictionary_name)
192*c154f397SPavel Labath    return PythonObject();
1936498aff2SJonas Devlieghere
1946498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(true);
1959d5e37edSPavel Labath  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
1969d5e37edSPavel Labath      session_dictionary_name);
1979d5e37edSPavel Labath  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
1989d5e37edSPavel Labath      python_class_name, dict);
1996498aff2SJonas Devlieghere
2006498aff2SJonas Devlieghere  if (!pfunc.IsAllocated())
201*c154f397SPavel Labath    return PythonObject();
2026498aff2SJonas Devlieghere
203*c154f397SPavel Labath  return pfunc(ToSWIGWrapper(std::move(debugger_sp)), dict);
2046498aff2SJonas Devlieghere}
2056498aff2SJonas Devlieghere
206*c154f397SPavel LabathPythonObject lldb_private::LLDBSwigPythonCreateScriptedProcess(
2079d5e37edSPavel Labath    const char *python_class_name, const char *session_dictionary_name,
2081f6a57c1SMed Ismail Bennani    const lldb::TargetSP &target_sp,
20982de8df2SPavel Labath    const lldb_private::StructuredDataImpl &args_impl,
2109d5e37edSPavel Labath    std::string &error_string) {
2119d5e37edSPavel Labath  if (python_class_name == NULL || python_class_name[0] == '\0' ||
2129d5e37edSPavel Labath      !session_dictionary_name)
213*c154f397SPavel Labath    return PythonObject();
2141f6a57c1SMed Ismail Bennani
2151f6a57c1SMed Ismail Bennani  PyErr_Cleaner py_err_cleaner(true);
2161f6a57c1SMed Ismail Bennani
2179d5e37edSPavel Labath  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
2189d5e37edSPavel Labath      session_dictionary_name);
2199d5e37edSPavel Labath  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
2209d5e37edSPavel Labath      python_class_name, dict);
2211f6a57c1SMed Ismail Bennani
2221f6a57c1SMed Ismail Bennani  if (!pfunc.IsAllocated()) {
2231f6a57c1SMed Ismail Bennani    error_string.append("could not find script class: ");
2241f6a57c1SMed Ismail Bennani    error_string.append(python_class_name);
225*c154f397SPavel Labath    return PythonObject();
2261f6a57c1SMed Ismail Bennani  }
2271f6a57c1SMed Ismail Bennani
2287f09ab08SPavel Labath  PythonObject target_arg = ToSWIGWrapper(target_sp);
2291f6a57c1SMed Ismail Bennani
2301f6a57c1SMed Ismail Bennani  llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
2311f6a57c1SMed Ismail Bennani  if (!arg_info) {
2321f6a57c1SMed Ismail Bennani    llvm::handleAllErrors(
2331f6a57c1SMed Ismail Bennani        arg_info.takeError(),
2349d5e37edSPavel Labath        [&](PythonException &E) { error_string.append(E.ReadBacktrace()); },
2351f6a57c1SMed Ismail Bennani        [&](const llvm::ErrorInfoBase &E) {
2361f6a57c1SMed Ismail Bennani          error_string.append(E.message());
2371f6a57c1SMed Ismail Bennani        });
238*c154f397SPavel Labath    return PythonObject();
2391f6a57c1SMed Ismail Bennani  }
2401f6a57c1SMed Ismail Bennani
2411f6a57c1SMed Ismail Bennani  PythonObject result = {};
2421f6a57c1SMed Ismail Bennani  if (arg_info.get().max_positional_args == 2) {
243ebb6bb72SPavel Labath    result = pfunc(target_arg, ToSWIGWrapper(args_impl));
2441f6a57c1SMed Ismail Bennani  } else {
2459d5e37edSPavel Labath    error_string.assign("wrong number of arguments in __init__, should be 2 "
2469d5e37edSPavel Labath                        "(not including self)");
247*c154f397SPavel Labath  }
248*c154f397SPavel Labath  return result;
2491f6a57c1SMed Ismail Bennani}
2501f6a57c1SMed Ismail Bennani
251*c154f397SPavel LabathPythonObject lldb_private::LLDBSwigPythonCreateScriptedThread(
2529d5e37edSPavel Labath    const char *python_class_name, const char *session_dictionary_name,
2539d5e37edSPavel Labath    const lldb::ProcessSP &process_sp, const StructuredDataImpl &args_impl,
2549d5e37edSPavel Labath    std::string &error_string) {
2559d5e37edSPavel Labath  if (python_class_name == NULL || python_class_name[0] == '\0' ||
2569d5e37edSPavel Labath      !session_dictionary_name)
257*c154f397SPavel Labath    return PythonObject();
25859d8dd79SMed Ismail Bennani
25959d8dd79SMed Ismail Bennani  PyErr_Cleaner py_err_cleaner(true);
26059d8dd79SMed Ismail Bennani
2619d5e37edSPavel Labath  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
2629d5e37edSPavel Labath      session_dictionary_name);
2639d5e37edSPavel Labath  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
2649d5e37edSPavel Labath      python_class_name, dict);
26559d8dd79SMed Ismail Bennani
26659d8dd79SMed Ismail Bennani  if (!pfunc.IsAllocated()) {
26759d8dd79SMed Ismail Bennani    error_string.append("could not find script class: ");
26859d8dd79SMed Ismail Bennani    error_string.append(python_class_name);
269*c154f397SPavel Labath    return PythonObject();
27059d8dd79SMed Ismail Bennani  }
27159d8dd79SMed Ismail Bennani
27259d8dd79SMed Ismail Bennani  llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
27359d8dd79SMed Ismail Bennani  if (!arg_info) {
27459d8dd79SMed Ismail Bennani    llvm::handleAllErrors(
27559d8dd79SMed Ismail Bennani        arg_info.takeError(),
2769d5e37edSPavel Labath        [&](PythonException &E) { error_string.append(E.ReadBacktrace()); },
27759d8dd79SMed Ismail Bennani        [&](const llvm::ErrorInfoBase &E) {
27859d8dd79SMed Ismail Bennani          error_string.append(E.message());
27959d8dd79SMed Ismail Bennani        });
280*c154f397SPavel Labath    return PythonObject();
28159d8dd79SMed Ismail Bennani  }
28259d8dd79SMed Ismail Bennani
283*c154f397SPavel Labath  if (arg_info.get().max_positional_args == 2)
284*c154f397SPavel Labath    return pfunc(ToSWIGWrapper(process_sp), ToSWIGWrapper(args_impl));
285*c154f397SPavel Labath
2869d5e37edSPavel Labath  error_string.assign("wrong number of arguments in __init__, should be 2 "
2879d5e37edSPavel Labath                      "(not including self)");
288*c154f397SPavel Labath  return PythonObject();
28959d8dd79SMed Ismail Bennani}
29059d8dd79SMed Ismail Bennani
291*c154f397SPavel LabathPythonObject lldb_private::LLDBSwigPythonCreateScriptedThreadPlan(
2929d5e37edSPavel Labath    const char *python_class_name, const char *session_dictionary_name,
29382de8df2SPavel Labath    const lldb_private::StructuredDataImpl &args_impl,
2949d5e37edSPavel Labath    std::string &error_string, const lldb::ThreadPlanSP &thread_plan_sp) {
2959d5e37edSPavel Labath  if (python_class_name == NULL || python_class_name[0] == '\0' ||
2969d5e37edSPavel Labath      !session_dictionary_name)
297*c154f397SPavel Labath    return PythonObject();
2986498aff2SJonas Devlieghere
2996498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(true);
3006498aff2SJonas Devlieghere
3019d5e37edSPavel Labath  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
3029d5e37edSPavel Labath      session_dictionary_name);
3039d5e37edSPavel Labath  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
3049d5e37edSPavel Labath      python_class_name, dict);
3056498aff2SJonas Devlieghere
3066498aff2SJonas Devlieghere  if (!pfunc.IsAllocated()) {
3076498aff2SJonas Devlieghere    error_string.append("could not find script class: ");
3086498aff2SJonas Devlieghere    error_string.append(python_class_name);
309*c154f397SPavel Labath    return PythonObject();
3106498aff2SJonas Devlieghere  }
3116498aff2SJonas Devlieghere
3127f09ab08SPavel Labath  PythonObject tp_arg = ToSWIGWrapper(thread_plan_sp);
3136498aff2SJonas Devlieghere
3146498aff2SJonas Devlieghere  llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
3156498aff2SJonas Devlieghere  if (!arg_info) {
3166498aff2SJonas Devlieghere    llvm::handleAllErrors(
3176498aff2SJonas Devlieghere        arg_info.takeError(),
3189d5e37edSPavel Labath        [&](PythonException &E) { error_string.append(E.ReadBacktrace()); },
3196498aff2SJonas Devlieghere        [&](const llvm::ErrorInfoBase &E) {
3206498aff2SJonas Devlieghere          error_string.append(E.message());
3216498aff2SJonas Devlieghere        });
322*c154f397SPavel Labath    return PythonObject();
3236498aff2SJonas Devlieghere  }
3246498aff2SJonas Devlieghere
3256498aff2SJonas Devlieghere  PythonObject result = {};
326ebb6bb72SPavel Labath  auto args_sb = std::make_unique<lldb::SBStructuredData>(args_impl);
3276498aff2SJonas Devlieghere  if (arg_info.get().max_positional_args == 2) {
32882de8df2SPavel Labath    if (args_sb->IsValid()) {
3299d5e37edSPavel Labath      error_string.assign(
3309d5e37edSPavel Labath          "args passed, but __init__ does not take an args dictionary");
331*c154f397SPavel Labath      return PythonObject();
3326498aff2SJonas Devlieghere    }
3336498aff2SJonas Devlieghere    result = pfunc(tp_arg, dict);
3346498aff2SJonas Devlieghere  } else if (arg_info.get().max_positional_args >= 3) {
335ebb6bb72SPavel Labath    result = pfunc(tp_arg, ToSWIGWrapper(std::move(args_sb)), dict);
3366498aff2SJonas Devlieghere  } else {
3379d5e37edSPavel Labath    error_string.assign("wrong number of arguments in __init__, should be 2 or "
3389d5e37edSPavel Labath                        "3 (not including self)");
339*c154f397SPavel Labath    return PythonObject();
3406498aff2SJonas Devlieghere  }
3416498aff2SJonas Devlieghere
3429d5e37edSPavel Labath  // FIXME: At this point we should check that the class we found supports all
3439d5e37edSPavel Labath  // the methods that we need.
3446498aff2SJonas Devlieghere
345*c154f397SPavel Labath  return result;
3466498aff2SJonas Devlieghere}
3476498aff2SJonas Devlieghere
3489d5e37edSPavel Labathbool lldb_private::LLDBSWIGPythonCallThreadPlan(
3499d5e37edSPavel Labath    void *implementor, const char *method_name, lldb_private::Event *event,
3509d5e37edSPavel Labath    bool &got_error) {
3516498aff2SJonas Devlieghere  got_error = false;
3526498aff2SJonas Devlieghere
3536498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(false);
3546498aff2SJonas Devlieghere  PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
3556498aff2SJonas Devlieghere  auto pfunc = self.ResolveName<PythonCallable>(method_name);
3566498aff2SJonas Devlieghere
3576498aff2SJonas Devlieghere  if (!pfunc.IsAllocated())
3586498aff2SJonas Devlieghere    return false;
3596498aff2SJonas Devlieghere
3606498aff2SJonas Devlieghere  PythonObject result;
3619d5e37edSPavel Labath  if (event != nullptr) {
3620a07c966SPavel Labath    ScopedPythonObject<SBEvent> event_arg = ToSWIGWrapper(event);
3630a07c966SPavel Labath    result = pfunc(event_arg.obj());
3649d5e37edSPavel Labath  } else
3656498aff2SJonas Devlieghere    result = pfunc();
3666498aff2SJonas Devlieghere
3679d5e37edSPavel Labath  if (PyErr_Occurred()) {
3686498aff2SJonas Devlieghere    got_error = true;
3699d5e37edSPavel Labath    printf("Return value was neither false nor true for call to %s.\n",
3709d5e37edSPavel Labath           method_name);
3716498aff2SJonas Devlieghere    PyErr_Print();
3726498aff2SJonas Devlieghere    return false;
3736498aff2SJonas Devlieghere  }
3746498aff2SJonas Devlieghere
3756498aff2SJonas Devlieghere  if (result.get() == Py_True)
3766498aff2SJonas Devlieghere    return true;
3776498aff2SJonas Devlieghere  else if (result.get() == Py_False)
3786498aff2SJonas Devlieghere    return false;
3796498aff2SJonas Devlieghere
3806498aff2SJonas Devlieghere  // Somebody returned the wrong thing...
3816498aff2SJonas Devlieghere  got_error = true;
3826498aff2SJonas Devlieghere  printf("Wrong return value type for call to %s.\n", method_name);
3836498aff2SJonas Devlieghere  return false;
3846498aff2SJonas Devlieghere}
3856498aff2SJonas Devlieghere
386*c154f397SPavel LabathPythonObject lldb_private::LLDBSwigPythonCreateScriptedBreakpointResolver(
3877f09ab08SPavel Labath    const char *python_class_name, const char *session_dictionary_name,
38882de8df2SPavel Labath    const StructuredDataImpl &args_impl,
3897f09ab08SPavel Labath    const lldb::BreakpointSP &breakpoint_sp) {
3907f09ab08SPavel Labath
3919d5e37edSPavel Labath  if (python_class_name == NULL || python_class_name[0] == '\0' ||
3929d5e37edSPavel Labath      !session_dictionary_name)
393*c154f397SPavel Labath    return PythonObject();
3946498aff2SJonas Devlieghere
3956498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(true);
3966498aff2SJonas Devlieghere
3979d5e37edSPavel Labath  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
3989d5e37edSPavel Labath      session_dictionary_name);
3999d5e37edSPavel Labath  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
4009d5e37edSPavel Labath      python_class_name, dict);
4016498aff2SJonas Devlieghere
4026498aff2SJonas Devlieghere  if (!pfunc.IsAllocated())
403*c154f397SPavel Labath    return PythonObject();
4046498aff2SJonas Devlieghere
405ebb6bb72SPavel Labath  PythonObject result =
406ebb6bb72SPavel Labath      pfunc(ToSWIGWrapper(breakpoint_sp), ToSWIGWrapper(args_impl), dict);
4079d5e37edSPavel Labath  // FIXME: At this point we should check that the class we found supports all
4089d5e37edSPavel Labath  // the methods that we need.
4096498aff2SJonas Devlieghere
4109d5e37edSPavel Labath  if (result.IsAllocated()) {
4116498aff2SJonas Devlieghere    // Check that __callback__ is defined:
4126498aff2SJonas Devlieghere    auto callback_func = result.ResolveName<PythonCallable>("__callback__");
4136498aff2SJonas Devlieghere    if (callback_func.IsAllocated())
414*c154f397SPavel Labath      return result;
4156498aff2SJonas Devlieghere  }
416*c154f397SPavel Labath  return PythonObject();
4176498aff2SJonas Devlieghere}
4186498aff2SJonas Devlieghere
4199d5e37edSPavel Labathunsigned int lldb_private::LLDBSwigPythonCallBreakpointResolver(
4209d5e37edSPavel Labath    void *implementor, const char *method_name,
4219d5e37edSPavel Labath    lldb_private::SymbolContext *sym_ctx) {
4226498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(false);
4236498aff2SJonas Devlieghere  PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
4246498aff2SJonas Devlieghere  auto pfunc = self.ResolveName<PythonCallable>(method_name);
4256498aff2SJonas Devlieghere
4266498aff2SJonas Devlieghere  if (!pfunc.IsAllocated())
4276498aff2SJonas Devlieghere    return 0;
4286498aff2SJonas Devlieghere
4292efc6892SPavel Labath  PythonObject result = sym_ctx ? pfunc(ToSWIGWrapper(*sym_ctx)) : pfunc();
4306498aff2SJonas Devlieghere
4319d5e37edSPavel Labath  if (PyErr_Occurred()) {
4326498aff2SJonas Devlieghere    PyErr_Print();
43352712d3fSLawrence D'Anna    PyErr_Clear();
4346498aff2SJonas Devlieghere    return 0;
4356498aff2SJonas Devlieghere  }
4366498aff2SJonas Devlieghere
4376498aff2SJonas Devlieghere  // The callback will return a bool, but we're need to also return ints
4386498aff2SJonas Devlieghere  // so we're squirrelling the bool through as an int...  And if you return
4396498aff2SJonas Devlieghere  // nothing, we'll continue.
4406498aff2SJonas Devlieghere  if (strcmp(method_name, "__callback__") == 0) {
4416498aff2SJonas Devlieghere    if (result.get() == Py_False)
4426498aff2SJonas Devlieghere      return 0;
4436498aff2SJonas Devlieghere    else
4446498aff2SJonas Devlieghere      return 1;
4456498aff2SJonas Devlieghere  }
4466498aff2SJonas Devlieghere
44752712d3fSLawrence D'Anna  long long ret_val = unwrapOrSetPythonException(As<long long>(result));
448478619cfSMuhammad Omair Javaid
44952712d3fSLawrence D'Anna  if (PyErr_Occurred()) {
45052712d3fSLawrence D'Anna    PyErr_Print();
45152712d3fSLawrence D'Anna    PyErr_Clear();
45252712d3fSLawrence D'Anna    return 0;
45352712d3fSLawrence D'Anna  }
4546498aff2SJonas Devlieghere
4556498aff2SJonas Devlieghere  return ret_val;
4566498aff2SJonas Devlieghere}
4576498aff2SJonas Devlieghere
458*c154f397SPavel LabathPythonObject lldb_private::LLDBSwigPythonCreateScriptedStopHook(
4599d5e37edSPavel Labath    lldb::TargetSP target_sp, const char *python_class_name,
4609d5e37edSPavel Labath    const char *session_dictionary_name, const StructuredDataImpl &args_impl,
4619d5e37edSPavel Labath    Status &error) {
4621b1d9815SJim Ingham  if (python_class_name == NULL || python_class_name[0] == '\0') {
4631b1d9815SJim Ingham    error.SetErrorString("Empty class name.");
464*c154f397SPavel Labath    return PythonObject();
4651b1d9815SJim Ingham  }
4661b1d9815SJim Ingham  if (!session_dictionary_name) {
4671b1d9815SJim Ingham    error.SetErrorString("No session dictionary");
468*c154f397SPavel Labath    return PythonObject();
4691b1d9815SJim Ingham  }
4701b1d9815SJim Ingham
4711b1d9815SJim Ingham  PyErr_Cleaner py_err_cleaner(true);
4721b1d9815SJim Ingham
4739d5e37edSPavel Labath  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
4741b1d9815SJim Ingham      session_dictionary_name);
4759d5e37edSPavel Labath  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
4761b1d9815SJim Ingham      python_class_name, dict);
4771b1d9815SJim Ingham
4781b1d9815SJim Ingham  if (!pfunc.IsAllocated()) {
4791b1d9815SJim Ingham    error.SetErrorStringWithFormat("Could not find class: %s.",
4801b1d9815SJim Ingham                                   python_class_name);
481*c154f397SPavel Labath    return PythonObject();
4821b1d9815SJim Ingham  }
4831b1d9815SJim Ingham
484ebb6bb72SPavel Labath  PythonObject result =
485ebb6bb72SPavel Labath      pfunc(ToSWIGWrapper(target_sp), ToSWIGWrapper(args_impl), dict);
4861b1d9815SJim Ingham
4879d5e37edSPavel Labath  if (result.IsAllocated()) {
4881b1d9815SJim Ingham    // Check that the handle_stop callback is defined:
4891b1d9815SJim Ingham    auto callback_func = result.ResolveName<PythonCallable>("handle_stop");
4901b1d9815SJim Ingham    if (callback_func.IsAllocated()) {
4911b1d9815SJim Ingham      if (auto args_info = callback_func.GetArgInfo()) {
4921b1d9815SJim Ingham        size_t num_args = (*args_info).max_positional_args;
4931b1d9815SJim Ingham        if (num_args != 2) {
4949d5e37edSPavel Labath          error.SetErrorStringWithFormat(
4959d5e37edSPavel Labath              "Wrong number of args for "
4962f95c50aSRichard Smith              "handle_stop callback, should be 2 (excluding self), got: %zu",
4971b1d9815SJim Ingham              num_args);
498*c154f397SPavel Labath          return PythonObject();
4991b1d9815SJim Ingham        } else
500*c154f397SPavel Labath          return result;
5011b1d9815SJim Ingham      } else {
5021b1d9815SJim Ingham        error.SetErrorString("Couldn't get num arguments for handle_stop "
5031b1d9815SJim Ingham                             "callback.");
504*c154f397SPavel Labath        return PythonObject();
5051b1d9815SJim Ingham      }
506*c154f397SPavel Labath      return result;
5079d5e37edSPavel Labath    } else {
5081b1d9815SJim Ingham      error.SetErrorStringWithFormat("Class \"%s\" is missing the required "
5091b1d9815SJim Ingham                                     "handle_stop callback.",
5101b1d9815SJim Ingham                                     python_class_name);
5111b1d9815SJim Ingham    }
5121b1d9815SJim Ingham  }
513*c154f397SPavel Labath  return PythonObject();
5141b1d9815SJim Ingham}
5151b1d9815SJim Ingham
5169d5e37edSPavel Labathbool lldb_private::LLDBSwigPythonStopHookCallHandleStop(
5179d5e37edSPavel Labath    void *implementor, lldb::ExecutionContextRefSP exc_ctx_sp,
5189d5e37edSPavel Labath    lldb::StreamSP stream) {
5191b1d9815SJim Ingham  // handle_stop will return a bool with the meaning "should_stop"...
5201b1d9815SJim Ingham  // If you return nothing we'll assume we are going to stop.
5211b1d9815SJim Ingham  // Also any errors should return true, since we should stop on error.
5221b1d9815SJim Ingham
5231b1d9815SJim Ingham  PyErr_Cleaner py_err_cleaner(false);
5241b1d9815SJim Ingham  PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
5251b1d9815SJim Ingham  auto pfunc = self.ResolveName<PythonCallable>("handle_stop");
5261b1d9815SJim Ingham
5271b1d9815SJim Ingham  if (!pfunc.IsAllocated())
5281b1d9815SJim Ingham    return true;
5291b1d9815SJim Ingham
5302efc6892SPavel Labath  auto *sb_stream = new lldb::SBStream();
5312efc6892SPavel Labath  PythonObject sb_stream_arg =
5322efc6892SPavel Labath      ToSWIGWrapper(std::unique_ptr<lldb::SBStream>(sb_stream));
5332efc6892SPavel Labath  PythonObject result =
5342efc6892SPavel Labath      pfunc(ToSWIGWrapper(std::move(exc_ctx_sp)), sb_stream_arg);
5351b1d9815SJim Ingham
5369d5e37edSPavel Labath  if (PyErr_Occurred()) {
5371b1d9815SJim Ingham    stream->PutCString("Python error occurred handling stop-hook.");
5381b1d9815SJim Ingham    PyErr_Print();
5391b1d9815SJim Ingham    PyErr_Clear();
5401b1d9815SJim Ingham    return true;
5411b1d9815SJim Ingham  }
5421b1d9815SJim Ingham
5431b1d9815SJim Ingham  // Now add the result to the output stream.  SBStream only
5441b1d9815SJim Ingham  // makes an internally help StreamString which I can't interpose, so I
5451b1d9815SJim Ingham  // have to copy it over here.
5462efc6892SPavel Labath  stream->PutCString(sb_stream->GetData());
5471b1d9815SJim Ingham
5481b1d9815SJim Ingham  if (result.get() == Py_False)
5491b1d9815SJim Ingham    return false;
5501b1d9815SJim Ingham  else
5511b1d9815SJim Ingham    return true;
5521b1d9815SJim Ingham}
5531b1d9815SJim Ingham
5549d5e37edSPavel Labath// wrapper that calls an optional instance member of an object taking no
5559d5e37edSPavel Labath// arguments
5569d5e37edSPavel Labathstatic PyObject *LLDBSwigPython_CallOptionalMember(
5579d5e37edSPavel Labath    PyObject * implementor, char *callee_name,
5589d5e37edSPavel Labath    PyObject *ret_if_not_found = Py_None, bool *was_found = NULL) {
5596498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(false);
5606498aff2SJonas Devlieghere
5616498aff2SJonas Devlieghere  PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
5626498aff2SJonas Devlieghere  auto pfunc = self.ResolveName<PythonCallable>(callee_name);
5636498aff2SJonas Devlieghere
5649d5e37edSPavel Labath  if (!pfunc.IsAllocated()) {
5656498aff2SJonas Devlieghere    if (was_found)
5666498aff2SJonas Devlieghere      *was_found = false;
5676498aff2SJonas Devlieghere    Py_XINCREF(ret_if_not_found);
5686498aff2SJonas Devlieghere    return ret_if_not_found;
5696498aff2SJonas Devlieghere  }
5706498aff2SJonas Devlieghere
5716498aff2SJonas Devlieghere  if (was_found)
5726498aff2SJonas Devlieghere    *was_found = true;
5736498aff2SJonas Devlieghere
5746498aff2SJonas Devlieghere  PythonObject result = pfunc();
5756498aff2SJonas Devlieghere  return result.release();
5766498aff2SJonas Devlieghere}
5776498aff2SJonas Devlieghere
5789d5e37edSPavel Labathsize_t lldb_private::LLDBSwigPython_CalculateNumChildren(PyObject * implementor,
5799d5e37edSPavel Labath                                                         uint32_t max) {
5806498aff2SJonas Devlieghere  PythonObject self(PyRefType::Borrowed, implementor);
5816498aff2SJonas Devlieghere  auto pfunc = self.ResolveName<PythonCallable>("num_children");
5826498aff2SJonas Devlieghere
5836498aff2SJonas Devlieghere  if (!pfunc.IsAllocated())
5846498aff2SJonas Devlieghere    return 0;
5856498aff2SJonas Devlieghere
5866498aff2SJonas Devlieghere  auto arg_info = pfunc.GetArgInfo();
5876498aff2SJonas Devlieghere  if (!arg_info) {
5886498aff2SJonas Devlieghere    llvm::consumeError(arg_info.takeError());
5896498aff2SJonas Devlieghere    return 0;
5906498aff2SJonas Devlieghere  }
5916498aff2SJonas Devlieghere
59252712d3fSLawrence D'Anna  size_t ret_val;
593478619cfSMuhammad Omair Javaid  if (arg_info.get().max_positional_args < 1)
59452712d3fSLawrence D'Anna    ret_val = unwrapOrSetPythonException(As<long long>(pfunc.Call()));
595478619cfSMuhammad Omair Javaid  else
5969d5e37edSPavel Labath    ret_val = unwrapOrSetPythonException(
5979d5e37edSPavel Labath        As<long long>(pfunc.Call(PythonInteger(max))));
598478619cfSMuhammad Omair Javaid
5999d5e37edSPavel Labath  if (PyErr_Occurred()) {
6006498aff2SJonas Devlieghere    PyErr_Print();
6016498aff2SJonas Devlieghere    PyErr_Clear();
60252712d3fSLawrence D'Anna    return 0;
6036498aff2SJonas Devlieghere  }
6046498aff2SJonas Devlieghere
6056498aff2SJonas Devlieghere  if (arg_info.get().max_positional_args < 1)
6066498aff2SJonas Devlieghere    ret_val = std::min(ret_val, static_cast<size_t>(max));
6076498aff2SJonas Devlieghere
6086498aff2SJonas Devlieghere  return ret_val;
6096498aff2SJonas Devlieghere}
6106498aff2SJonas Devlieghere
6119d5e37edSPavel LabathPyObject *lldb_private::LLDBSwigPython_GetChildAtIndex(PyObject * implementor,
6129d5e37edSPavel Labath                                                       uint32_t idx) {
6136498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(true);
6146498aff2SJonas Devlieghere
6156498aff2SJonas Devlieghere  PythonObject self(PyRefType::Borrowed, implementor);
6166498aff2SJonas Devlieghere  auto pfunc = self.ResolveName<PythonCallable>("get_child_at_index");
6176498aff2SJonas Devlieghere
6186498aff2SJonas Devlieghere  if (!pfunc.IsAllocated())
6196498aff2SJonas Devlieghere    return nullptr;
6206498aff2SJonas Devlieghere
6216498aff2SJonas Devlieghere  PythonObject result = pfunc(PythonInteger(idx));
6226498aff2SJonas Devlieghere
6236498aff2SJonas Devlieghere  if (!result.IsAllocated())
6246498aff2SJonas Devlieghere    return nullptr;
6256498aff2SJonas Devlieghere
6266498aff2SJonas Devlieghere  lldb::SBValue *sbvalue_ptr = nullptr;
6279d5e37edSPavel Labath  if (SWIG_ConvertPtr(result.get(), (void **)&sbvalue_ptr,
6289d5e37edSPavel Labath                      SWIGTYPE_p_lldb__SBValue, 0) == -1)
6296498aff2SJonas Devlieghere    return nullptr;
6306498aff2SJonas Devlieghere
6316498aff2SJonas Devlieghere  if (sbvalue_ptr == nullptr)
6326498aff2SJonas Devlieghere    return nullptr;
6336498aff2SJonas Devlieghere
6346498aff2SJonas Devlieghere  return result.release();
6356498aff2SJonas Devlieghere}
6366498aff2SJonas Devlieghere
6379d5e37edSPavel Labathint lldb_private::LLDBSwigPython_GetIndexOfChildWithName(
6389d5e37edSPavel Labath    PyObject * implementor, const char *child_name) {
6396498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(true);
6406498aff2SJonas Devlieghere
6416498aff2SJonas Devlieghere  PythonObject self(PyRefType::Borrowed, implementor);
6426498aff2SJonas Devlieghere  auto pfunc = self.ResolveName<PythonCallable>("get_child_index");
6436498aff2SJonas Devlieghere
6446498aff2SJonas Devlieghere  if (!pfunc.IsAllocated())
6456498aff2SJonas Devlieghere    return UINT32_MAX;
6466498aff2SJonas Devlieghere
64752712d3fSLawrence D'Anna  llvm::Expected<PythonObject> result = pfunc.Call(PythonString(child_name));
6486498aff2SJonas Devlieghere
6499d5e37edSPavel Labath  long long retval =
6509d5e37edSPavel Labath      unwrapOrSetPythonException(As<long long>(std::move(result)));
65152712d3fSLawrence D'Anna
65252712d3fSLawrence D'Anna  if (PyErr_Occurred()) {
65352712d3fSLawrence D'Anna    PyErr_Clear(); // FIXME print this? do something else
6546498aff2SJonas Devlieghere    return UINT32_MAX;
65552712d3fSLawrence D'Anna  }
6566498aff2SJonas Devlieghere
6576498aff2SJonas Devlieghere  if (retval >= 0)
6586498aff2SJonas Devlieghere    return (uint32_t)retval;
6596498aff2SJonas Devlieghere
6606498aff2SJonas Devlieghere  return UINT32_MAX;
6616498aff2SJonas Devlieghere}
6626498aff2SJonas Devlieghere
6639d5e37edSPavel Labathbool lldb_private::LLDBSwigPython_UpdateSynthProviderInstance(PyObject *
6649d5e37edSPavel Labath                                                              implementor) {
6656498aff2SJonas Devlieghere  bool ret_val = false;
6666498aff2SJonas Devlieghere
6676498aff2SJonas Devlieghere  static char callee_name[] = "update";
6686498aff2SJonas Devlieghere
6699d5e37edSPavel Labath  PyObject *py_return =
6709d5e37edSPavel Labath      LLDBSwigPython_CallOptionalMember(implementor, callee_name);
6716498aff2SJonas Devlieghere
6726498aff2SJonas Devlieghere  if (py_return == Py_True)
6736498aff2SJonas Devlieghere    ret_val = true;
6746498aff2SJonas Devlieghere
6756498aff2SJonas Devlieghere  Py_XDECREF(py_return);
6766498aff2SJonas Devlieghere
6776498aff2SJonas Devlieghere  return ret_val;
6786498aff2SJonas Devlieghere}
6796498aff2SJonas Devlieghere
6809d5e37edSPavel Labathbool lldb_private::LLDBSwigPython_MightHaveChildrenSynthProviderInstance(
6819d5e37edSPavel Labath    PyObject * implementor) {
6826498aff2SJonas Devlieghere  bool ret_val = false;
6836498aff2SJonas Devlieghere
6846498aff2SJonas Devlieghere  static char callee_name[] = "has_children";
6856498aff2SJonas Devlieghere
6869d5e37edSPavel Labath  PyObject *py_return =
6879d5e37edSPavel Labath      LLDBSwigPython_CallOptionalMember(implementor, callee_name, Py_True);
6886498aff2SJonas Devlieghere
6896498aff2SJonas Devlieghere  if (py_return == Py_True)
6906498aff2SJonas Devlieghere    ret_val = true;
6916498aff2SJonas Devlieghere
6926498aff2SJonas Devlieghere  Py_XDECREF(py_return);
6936498aff2SJonas Devlieghere
6946498aff2SJonas Devlieghere  return ret_val;
6956498aff2SJonas Devlieghere}
6966498aff2SJonas Devlieghere
6979d5e37edSPavel LabathPyObject *lldb_private::LLDBSwigPython_GetValueSynthProviderInstance(
6989d5e37edSPavel Labath    PyObject * implementor) {
6996498aff2SJonas Devlieghere  PyObject *ret_val = nullptr;
7006498aff2SJonas Devlieghere
7016498aff2SJonas Devlieghere  static char callee_name[] = "get_value";
7026498aff2SJonas Devlieghere
7039d5e37edSPavel Labath  PyObject *py_return =
7049d5e37edSPavel Labath      LLDBSwigPython_CallOptionalMember(implementor, callee_name, Py_None);
7056498aff2SJonas Devlieghere
7066498aff2SJonas Devlieghere  if (py_return == Py_None || py_return == nullptr)
7076498aff2SJonas Devlieghere    ret_val = nullptr;
7086498aff2SJonas Devlieghere
7096498aff2SJonas Devlieghere  lldb::SBValue *sbvalue_ptr = NULL;
7106498aff2SJonas Devlieghere
7119d5e37edSPavel Labath  if (SWIG_ConvertPtr(py_return, (void **)&sbvalue_ptr,
7129d5e37edSPavel Labath                      SWIGTYPE_p_lldb__SBValue, 0) == -1)
7136498aff2SJonas Devlieghere    ret_val = nullptr;
7146498aff2SJonas Devlieghere  else if (sbvalue_ptr == NULL)
7156498aff2SJonas Devlieghere    ret_val = nullptr;
7166498aff2SJonas Devlieghere  else
7176498aff2SJonas Devlieghere    ret_val = py_return;
7186498aff2SJonas Devlieghere
7196498aff2SJonas Devlieghere  Py_XDECREF(py_return);
7206498aff2SJonas Devlieghere  return ret_val;
7216498aff2SJonas Devlieghere}
7226498aff2SJonas Devlieghere
7239d5e37edSPavel Labathvoid *lldb_private::LLDBSWIGPython_CastPyObjectToSBData(PyObject * data) {
7241f6a57c1SMed Ismail Bennani  lldb::SBData *sb_ptr = nullptr;
7251f6a57c1SMed Ismail Bennani
7269d5e37edSPavel Labath  int valid_cast =
7279d5e37edSPavel Labath      SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBData, 0);
7281f6a57c1SMed Ismail Bennani
7291f6a57c1SMed Ismail Bennani  if (valid_cast == -1)
7301f6a57c1SMed Ismail Bennani    return NULL;
7311f6a57c1SMed Ismail Bennani
7321f6a57c1SMed Ismail Bennani  return sb_ptr;
7331f6a57c1SMed Ismail Bennani}
7341f6a57c1SMed Ismail Bennani
7359d5e37edSPavel Labathvoid *lldb_private::LLDBSWIGPython_CastPyObjectToSBError(PyObject * data) {
7361f6a57c1SMed Ismail Bennani  lldb::SBError *sb_ptr = nullptr;
7371f6a57c1SMed Ismail Bennani
7389d5e37edSPavel Labath  int valid_cast =
7399d5e37edSPavel Labath      SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBError, 0);
7401f6a57c1SMed Ismail Bennani
7411f6a57c1SMed Ismail Bennani  if (valid_cast == -1)
7421f6a57c1SMed Ismail Bennani    return NULL;
7431f6a57c1SMed Ismail Bennani
7441f6a57c1SMed Ismail Bennani  return sb_ptr;
7451f6a57c1SMed Ismail Bennani}
7461f6a57c1SMed Ismail Bennani
7479d5e37edSPavel Labathvoid *lldb_private::LLDBSWIGPython_CastPyObjectToSBValue(PyObject * data) {
7486498aff2SJonas Devlieghere  lldb::SBValue *sb_ptr = NULL;
7496498aff2SJonas Devlieghere
7509d5e37edSPavel Labath  int valid_cast =
7519d5e37edSPavel Labath      SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBValue, 0);
7526498aff2SJonas Devlieghere
7536498aff2SJonas Devlieghere  if (valid_cast == -1)
7546498aff2SJonas Devlieghere    return NULL;
7556498aff2SJonas Devlieghere
7566498aff2SJonas Devlieghere  return sb_ptr;
7576498aff2SJonas Devlieghere}
7586498aff2SJonas Devlieghere
7599d5e37edSPavel Labathvoid *lldb_private::LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *
7609d5e37edSPavel Labath                                                                    data) {
761a758c9f7SMed Ismail Bennani  lldb::SBMemoryRegionInfo *sb_ptr = NULL;
762a758c9f7SMed Ismail Bennani
7639d5e37edSPavel Labath  int valid_cast = SWIG_ConvertPtr(data, (void **)&sb_ptr,
7649d5e37edSPavel Labath                                   SWIGTYPE_p_lldb__SBMemoryRegionInfo, 0);
765a758c9f7SMed Ismail Bennani
766a758c9f7SMed Ismail Bennani  if (valid_cast == -1)
767a758c9f7SMed Ismail Bennani    return NULL;
768a758c9f7SMed Ismail Bennani
769a758c9f7SMed Ismail Bennani  return sb_ptr;
770a758c9f7SMed Ismail Bennani}
771a758c9f7SMed Ismail Bennani
7729d5e37edSPavel Labathbool lldb_private::LLDBSwigPythonCallCommand(
7739d5e37edSPavel Labath    const char *python_function_name, const char *session_dictionary_name,
7747406d236SPavel Labath    lldb::DebuggerSP debugger, const char *args,
7756498aff2SJonas Devlieghere    lldb_private::CommandReturnObject &cmd_retobj,
7769d5e37edSPavel Labath    lldb::ExecutionContextRefSP exe_ctx_ref_sp) {
7776498aff2SJonas Devlieghere
7786498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(true);
7799d5e37edSPavel Labath  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
7809d5e37edSPavel Labath      session_dictionary_name);
7819d5e37edSPavel Labath  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
7829d5e37edSPavel Labath      python_function_name, dict);
7836498aff2SJonas Devlieghere
7846498aff2SJonas Devlieghere  if (!pfunc.IsAllocated())
7856498aff2SJonas Devlieghere    return false;
7866498aff2SJonas Devlieghere
7876498aff2SJonas Devlieghere  auto argc = pfunc.GetArgInfo();
7886498aff2SJonas Devlieghere  if (!argc) {
7896498aff2SJonas Devlieghere    llvm::consumeError(argc.takeError());
7906498aff2SJonas Devlieghere    return false;
7916498aff2SJonas Devlieghere  }
7927406d236SPavel Labath  PythonObject debugger_arg = ToSWIGWrapper(std::move(debugger));
7930a07c966SPavel Labath  auto cmd_retobj_arg = ToSWIGWrapper(cmd_retobj);
7946498aff2SJonas Devlieghere
7956498aff2SJonas Devlieghere  if (argc.get().max_positional_args < 5u)
7960a07c966SPavel Labath    pfunc(debugger_arg, PythonString(args), cmd_retobj_arg.obj(), dict);
7976498aff2SJonas Devlieghere  else
7982efc6892SPavel Labath    pfunc(debugger_arg, PythonString(args),
7990a07c966SPavel Labath          ToSWIGWrapper(std::move(exe_ctx_ref_sp)), cmd_retobj_arg.obj(), dict);
8006498aff2SJonas Devlieghere
8016498aff2SJonas Devlieghere  return true;
8026498aff2SJonas Devlieghere}
8036498aff2SJonas Devlieghere
8049d5e37edSPavel Labathbool lldb_private::LLDBSwigPythonCallCommandObject(
8057406d236SPavel Labath    PyObject *implementor, lldb::DebuggerSP debugger, const char *args,
8066498aff2SJonas Devlieghere    lldb_private::CommandReturnObject &cmd_retobj,
8079d5e37edSPavel Labath    lldb::ExecutionContextRefSP exe_ctx_ref_sp) {
8086498aff2SJonas Devlieghere
8096498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(true);
8106498aff2SJonas Devlieghere
8116498aff2SJonas Devlieghere  PythonObject self(PyRefType::Borrowed, implementor);
8126498aff2SJonas Devlieghere  auto pfunc = self.ResolveName<PythonCallable>("__call__");
8136498aff2SJonas Devlieghere
8146498aff2SJonas Devlieghere  if (!pfunc.IsAllocated())
8156498aff2SJonas Devlieghere    return false;
8166498aff2SJonas Devlieghere
8170a07c966SPavel Labath  auto cmd_retobj_arg = ToSWIGWrapper(cmd_retobj);
8186498aff2SJonas Devlieghere
8192efc6892SPavel Labath  pfunc(ToSWIGWrapper(std::move(debugger)), PythonString(args),
8200a07c966SPavel Labath        ToSWIGWrapper(exe_ctx_ref_sp), cmd_retobj_arg.obj());
8216498aff2SJonas Devlieghere
8226498aff2SJonas Devlieghere  return true;
8236498aff2SJonas Devlieghere}
8246498aff2SJonas Devlieghere
825*c154f397SPavel LabathPythonObject lldb_private::LLDBSWIGPythonCreateOSPlugin(
8269d5e37edSPavel Labath    const char *python_class_name, const char *session_dictionary_name,
8279d5e37edSPavel Labath    const lldb::ProcessSP &process_sp) {
8289d5e37edSPavel Labath  if (python_class_name == NULL || python_class_name[0] == '\0' ||
8299d5e37edSPavel Labath      !session_dictionary_name)
830*c154f397SPavel Labath    return PythonObject();
8316498aff2SJonas Devlieghere
8326498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(true);
8336498aff2SJonas Devlieghere
8349d5e37edSPavel Labath  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
8359d5e37edSPavel Labath      session_dictionary_name);
8369d5e37edSPavel Labath  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
8379d5e37edSPavel Labath      python_class_name, dict);
8386498aff2SJonas Devlieghere
8396498aff2SJonas Devlieghere  if (!pfunc.IsAllocated())
840*c154f397SPavel Labath    return PythonObject();
8416498aff2SJonas Devlieghere
842*c154f397SPavel Labath  return pfunc(ToSWIGWrapper(process_sp));
8436498aff2SJonas Devlieghere}
8446498aff2SJonas Devlieghere
845*c154f397SPavel LabathPythonObject lldb_private::LLDBSWIGPython_CreateFrameRecognizer(
8469d5e37edSPavel Labath    const char *python_class_name, const char *session_dictionary_name) {
8479d5e37edSPavel Labath  if (python_class_name == NULL || python_class_name[0] == '\0' ||
8489d5e37edSPavel Labath      !session_dictionary_name)
849*c154f397SPavel Labath    return PythonObject();
8506498aff2SJonas Devlieghere
8516498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(true);
8526498aff2SJonas Devlieghere
8539d5e37edSPavel Labath  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
8549d5e37edSPavel Labath      session_dictionary_name);
8559d5e37edSPavel Labath  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
8569d5e37edSPavel Labath      python_class_name, dict);
8576498aff2SJonas Devlieghere
8586498aff2SJonas Devlieghere  if (!pfunc.IsAllocated())
859*c154f397SPavel Labath    return PythonObject();
8606498aff2SJonas Devlieghere
861*c154f397SPavel Labath  return pfunc();
8626498aff2SJonas Devlieghere}
8636498aff2SJonas Devlieghere
8649d5e37edSPavel LabathPyObject *lldb_private::LLDBSwigPython_GetRecognizedArguments(
8659d5e37edSPavel Labath    PyObject * implementor, const lldb::StackFrameSP &frame_sp) {
8666498aff2SJonas Devlieghere  static char callee_name[] = "get_recognized_arguments";
8676498aff2SJonas Devlieghere
8687406d236SPavel Labath  PythonObject arg = ToSWIGWrapper(frame_sp);
8696498aff2SJonas Devlieghere
8706498aff2SJonas Devlieghere  PythonString str(callee_name);
8719d5e37edSPavel Labath  PyObject *result =
8726c2bf012SPavel Labath      PyObject_CallMethodObjArgs(implementor, str.get(), arg.get(), NULL);
8736498aff2SJonas Devlieghere  return result;
8746498aff2SJonas Devlieghere}
8756498aff2SJonas Devlieghere
8769d5e37edSPavel Labathvoid *lldb_private::LLDBSWIGPython_GetDynamicSetting(
8779d5e37edSPavel Labath    void *module, const char *setting, const lldb::TargetSP &target_sp) {
8786498aff2SJonas Devlieghere  if (!module || !setting)
8796498aff2SJonas Devlieghere    Py_RETURN_NONE;
8806498aff2SJonas Devlieghere
8816498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(true);
8826498aff2SJonas Devlieghere  PythonObject py_module(PyRefType::Borrowed, (PyObject *)module);
8836498aff2SJonas Devlieghere  auto pfunc = py_module.ResolveName<PythonCallable>("get_dynamic_setting");
8846498aff2SJonas Devlieghere
8856498aff2SJonas Devlieghere  if (!pfunc.IsAllocated())
8866498aff2SJonas Devlieghere    Py_RETURN_NONE;
8876498aff2SJonas Devlieghere
8887f09ab08SPavel Labath  auto result = pfunc(ToSWIGWrapper(target_sp), PythonString(setting));
8896498aff2SJonas Devlieghere
8906498aff2SJonas Devlieghere  return result.release();
8916498aff2SJonas Devlieghere}
8926498aff2SJonas Devlieghere
8939a14adeaSPavel Labathbool lldb_private::LLDBSWIGPythonRunScriptKeywordProcess(
8947f09ab08SPavel Labath    const char *python_function_name, const char *session_dictionary_name,
8957f09ab08SPavel Labath    const lldb::ProcessSP &process, std::string &output) {
8966498aff2SJonas Devlieghere
8979d5e37edSPavel Labath  if (python_function_name == NULL || python_function_name[0] == '\0' ||
8989d5e37edSPavel Labath      !session_dictionary_name)
8996498aff2SJonas Devlieghere    return false;
9006498aff2SJonas Devlieghere
9016498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(true);
9026498aff2SJonas Devlieghere
9039d5e37edSPavel Labath  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
9049d5e37edSPavel Labath      session_dictionary_name);
9059d5e37edSPavel Labath  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
9069d5e37edSPavel Labath      python_function_name, dict);
9076498aff2SJonas Devlieghere
9086498aff2SJonas Devlieghere  if (!pfunc.IsAllocated())
9096498aff2SJonas Devlieghere    return false;
9106498aff2SJonas Devlieghere
9117f09ab08SPavel Labath  auto result = pfunc(ToSWIGWrapper(process), dict);
9126498aff2SJonas Devlieghere
9136498aff2SJonas Devlieghere  output = result.Str().GetString().str();
9146498aff2SJonas Devlieghere
9156498aff2SJonas Devlieghere  return true;
9166498aff2SJonas Devlieghere}
9176498aff2SJonas Devlieghere
9187406d236SPavel Labathllvm::Optional<std::string> lldb_private::LLDBSWIGPythonRunScriptKeywordThread(
9199d5e37edSPavel Labath    const char *python_function_name, const char *session_dictionary_name,
9207406d236SPavel Labath    lldb::ThreadSP thread) {
9219d5e37edSPavel Labath  if (python_function_name == NULL || python_function_name[0] == '\0' ||
9229d5e37edSPavel Labath      !session_dictionary_name)
9237406d236SPavel Labath    return llvm::None;
9246498aff2SJonas Devlieghere
9256498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(true);
9266498aff2SJonas Devlieghere
9279d5e37edSPavel Labath  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
9289d5e37edSPavel Labath      session_dictionary_name);
9299d5e37edSPavel Labath  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
9309d5e37edSPavel Labath      python_function_name, dict);
9316498aff2SJonas Devlieghere
9326498aff2SJonas Devlieghere  if (!pfunc.IsAllocated())
9337406d236SPavel Labath    return llvm::None;
9346498aff2SJonas Devlieghere
9357406d236SPavel Labath  auto result = pfunc(ToSWIGWrapper(std::move(thread)), dict);
9366498aff2SJonas Devlieghere
9377406d236SPavel Labath  return result.Str().GetString().str();
9386498aff2SJonas Devlieghere}
9396498aff2SJonas Devlieghere
9409a14adeaSPavel Labathbool lldb_private::LLDBSWIGPythonRunScriptKeywordTarget(
9417f09ab08SPavel Labath    const char *python_function_name, const char *session_dictionary_name,
9427f09ab08SPavel Labath    const lldb::TargetSP &target, std::string &output) {
9436498aff2SJonas Devlieghere
9449d5e37edSPavel Labath  if (python_function_name == NULL || python_function_name[0] == '\0' ||
9459d5e37edSPavel Labath      !session_dictionary_name)
9466498aff2SJonas Devlieghere    return false;
9476498aff2SJonas Devlieghere
9486498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(true);
9496498aff2SJonas Devlieghere
9509d5e37edSPavel Labath  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
9519d5e37edSPavel Labath      session_dictionary_name);
9529d5e37edSPavel Labath  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
9539d5e37edSPavel Labath      python_function_name, dict);
9546498aff2SJonas Devlieghere
9556498aff2SJonas Devlieghere  if (!pfunc.IsAllocated())
9566498aff2SJonas Devlieghere    return false;
9576498aff2SJonas Devlieghere
9587f09ab08SPavel Labath  auto result = pfunc(ToSWIGWrapper(target), dict);
9596498aff2SJonas Devlieghere
9606498aff2SJonas Devlieghere  output = result.Str().GetString().str();
9616498aff2SJonas Devlieghere
9626498aff2SJonas Devlieghere  return true;
9636498aff2SJonas Devlieghere}
9646498aff2SJonas Devlieghere
9657406d236SPavel Labathllvm::Optional<std::string> lldb_private::LLDBSWIGPythonRunScriptKeywordFrame(
9669d5e37edSPavel Labath    const char *python_function_name, const char *session_dictionary_name,
9677406d236SPavel Labath    lldb::StackFrameSP frame) {
9689d5e37edSPavel Labath  if (python_function_name == NULL || python_function_name[0] == '\0' ||
9699d5e37edSPavel Labath      !session_dictionary_name)
9707406d236SPavel Labath    return llvm::None;
9716498aff2SJonas Devlieghere
9726498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(true);
9736498aff2SJonas Devlieghere
9749d5e37edSPavel Labath  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
9759d5e37edSPavel Labath      session_dictionary_name);
9769d5e37edSPavel Labath  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
9779d5e37edSPavel Labath      python_function_name, dict);
9786498aff2SJonas Devlieghere
9796498aff2SJonas Devlieghere  if (!pfunc.IsAllocated())
9807406d236SPavel Labath    return llvm::None;
9816498aff2SJonas Devlieghere
9827406d236SPavel Labath  auto result = pfunc(ToSWIGWrapper(std::move(frame)), dict);
9836498aff2SJonas Devlieghere
9847406d236SPavel Labath  return result.Str().GetString().str();
9856498aff2SJonas Devlieghere}
9866498aff2SJonas Devlieghere
9879a14adeaSPavel Labathbool lldb_private::LLDBSWIGPythonRunScriptKeywordValue(
9887f09ab08SPavel Labath    const char *python_function_name, const char *session_dictionary_name,
9897f09ab08SPavel Labath    const lldb::ValueObjectSP &value, std::string &output) {
9906498aff2SJonas Devlieghere
9919d5e37edSPavel Labath  if (python_function_name == NULL || python_function_name[0] == '\0' ||
9929d5e37edSPavel Labath      !session_dictionary_name)
9936498aff2SJonas Devlieghere    return false;
9946498aff2SJonas Devlieghere
9956498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(true);
9966498aff2SJonas Devlieghere
9979d5e37edSPavel Labath  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
9989d5e37edSPavel Labath      session_dictionary_name);
9999d5e37edSPavel Labath  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
10009d5e37edSPavel Labath      python_function_name, dict);
10016498aff2SJonas Devlieghere
10026498aff2SJonas Devlieghere  if (!pfunc.IsAllocated())
10036498aff2SJonas Devlieghere    return false;
10046498aff2SJonas Devlieghere
10057f09ab08SPavel Labath  auto result = pfunc(ToSWIGWrapper(value), dict);
10066498aff2SJonas Devlieghere
10076498aff2SJonas Devlieghere  output = result.Str().GetString().str();
10086498aff2SJonas Devlieghere
10096498aff2SJonas Devlieghere  return true;
10106498aff2SJonas Devlieghere}
10116498aff2SJonas Devlieghere
10129d5e37edSPavel Labathbool lldb_private::LLDBSwigPythonCallModuleInit(
10139d5e37edSPavel Labath    const char *python_module_name, const char *session_dictionary_name,
10147406d236SPavel Labath    lldb::DebuggerSP debugger) {
10156498aff2SJonas Devlieghere  std::string python_function_name_string = python_module_name;
10166498aff2SJonas Devlieghere  python_function_name_string += ".__lldb_init_module";
10176498aff2SJonas Devlieghere  const char *python_function_name = python_function_name_string.c_str();
10186498aff2SJonas Devlieghere
10196498aff2SJonas Devlieghere  PyErr_Cleaner py_err_cleaner(true);
10206498aff2SJonas Devlieghere
10219d5e37edSPavel Labath  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
10229d5e37edSPavel Labath      session_dictionary_name);
10239d5e37edSPavel Labath  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
10249d5e37edSPavel Labath      python_function_name, dict);
10256498aff2SJonas Devlieghere
10266498aff2SJonas Devlieghere  // This method is optional and need not exist.  So if we don't find it,
10276498aff2SJonas Devlieghere  // it's actually a success, not a failure.
10286498aff2SJonas Devlieghere  if (!pfunc.IsAllocated())
10296498aff2SJonas Devlieghere    return true;
10306498aff2SJonas Devlieghere
10317406d236SPavel Labath  pfunc(ToSWIGWrapper(std::move(debugger)), dict);
10326498aff2SJonas Devlieghere
10336498aff2SJonas Devlieghere  return true;
10346498aff2SJonas Devlieghere}
10356498aff2SJonas Devlieghere
10369d5e37edSPavel Labathlldb::ValueObjectSP lldb_private::LLDBSWIGPython_GetValueObjectSPFromSBValue(
10379d5e37edSPavel Labath    void *data) {
10386498aff2SJonas Devlieghere  lldb::ValueObjectSP valobj_sp;
10399d5e37edSPavel Labath  if (data) {
10406498aff2SJonas Devlieghere    lldb::SBValue *sb_ptr = (lldb::SBValue *)data;
10416498aff2SJonas Devlieghere    valobj_sp = sb_ptr->GetSP();
10426498aff2SJonas Devlieghere  }
10436498aff2SJonas Devlieghere  return valobj_sp;
10446498aff2SJonas Devlieghere}
10456498aff2SJonas Devlieghere
10466498aff2SJonas Devlieghere// For the LogOutputCallback functions
10479d5e37edSPavel Labathstatic void LLDBSwigPythonCallPythonLogOutputCallback(const char *str,
10489d5e37edSPavel Labath                                                      void *baton) {
10496498aff2SJonas Devlieghere  if (baton != Py_None) {
10506498aff2SJonas Devlieghere    SWIG_PYTHON_THREAD_BEGIN_BLOCK;
10519d5e37edSPavel Labath    PyObject *result = PyObject_CallFunction(
10529d5e37edSPavel Labath        reinterpret_cast<PyObject *>(baton), const_cast<char *>("s"), str);
10536498aff2SJonas Devlieghere    Py_XDECREF(result);
10546498aff2SJonas Devlieghere    SWIG_PYTHON_THREAD_END_BLOCK;
10556498aff2SJonas Devlieghere  }
10566498aff2SJonas Devlieghere}
10576498aff2SJonas Devlieghere%}
1058