1%header %{
2
3class PyErr_Cleaner {
4public:
5  PyErr_Cleaner(bool print = false) : m_print(print) {}
6
7  ~PyErr_Cleaner() {
8    if (PyErr_Occurred()) {
9      if (m_print && !PyErr_ExceptionMatches(PyExc_SystemExit))
10        PyErr_Print();
11      PyErr_Clear();
12    }
13  }
14
15private:
16  bool m_print;
17};
18
19llvm::Expected<bool> lldb_private::LLDBSwigPythonBreakpointCallbackFunction(
20    const char *python_function_name, const char *session_dictionary_name,
21    const lldb::StackFrameSP &frame_sp,
22    const lldb::BreakpointLocationSP &bp_loc_sp,
23    const lldb_private::StructuredDataImpl &args_impl) {
24  using namespace llvm;
25
26  lldb::SBBreakpointLocation sb_bp_loc(bp_loc_sp);
27
28  PyErr_Cleaner py_err_cleaner(true);
29  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
30      session_dictionary_name);
31  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
32      python_function_name, dict);
33
34  unsigned max_positional_args;
35  if (auto arg_info = pfunc.GetArgInfo())
36    max_positional_args = arg_info.get().max_positional_args;
37  else
38    return arg_info.takeError();
39
40  PythonObject frame_arg = ToSWIGWrapper(frame_sp);
41  PythonObject bp_loc_arg = ToSWIGWrapper(bp_loc_sp);
42
43  auto result =
44      max_positional_args < 4
45          ? pfunc.Call(frame_arg, bp_loc_arg, dict)
46          : pfunc.Call(frame_arg, bp_loc_arg, ToSWIGWrapper(args_impl), dict);
47
48  if (!result)
49    return result.takeError();
50
51  // Only False counts as false!
52  return result.get().get() != Py_False;
53}
54
55// resolve a dotted Python name in the form
56// foo.bar.baz.Foobar to an actual Python object
57// if pmodule is NULL, the __main__ module will be used
58// as the starting point for the search
59
60// This function is called by
61// lldb_private::ScriptInterpreterPython::BreakpointCallbackFunction(...) and is
62// used when a script command is attached to a breakpoint for execution.
63
64// This function is called by
65// lldb_private::ScriptInterpreterPython::WatchpointCallbackFunction(...) and is
66// used when a script command is attached to a watchpoint for execution.
67
68bool lldb_private::LLDBSwigPythonWatchpointCallbackFunction(
69    const char *python_function_name, const char *session_dictionary_name,
70    const lldb::StackFrameSP &frame_sp, const lldb::WatchpointSP &wp_sp) {
71
72  bool stop_at_watchpoint = true;
73
74  PyErr_Cleaner py_err_cleaner(true);
75
76  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
77      session_dictionary_name);
78  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
79      python_function_name, dict);
80
81  if (!pfunc.IsAllocated())
82    return stop_at_watchpoint;
83
84  PythonObject result =
85      pfunc(ToSWIGWrapper(frame_sp), ToSWIGWrapper(wp_sp), dict);
86
87  if (result.get() == Py_False)
88    stop_at_watchpoint = false;
89
90  return stop_at_watchpoint;
91}
92
93bool lldb_private::LLDBSwigPythonCallTypeScript(
94    const char *python_function_name, const void *session_dictionary,
95    const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper,
96    const lldb::TypeSummaryOptionsSP &options_sp, std::string &retval) {
97
98  retval.clear();
99
100  if (!python_function_name || !session_dictionary)
101    return false;
102
103  PyObject *pfunc_impl = nullptr;
104
105  if (pyfunct_wrapper && *pyfunct_wrapper &&
106      PyFunction_Check(*pyfunct_wrapper)) {
107    pfunc_impl = (PyObject *)(*pyfunct_wrapper);
108    if (pfunc_impl->ob_refcnt == 1) {
109      Py_XDECREF(pfunc_impl);
110      pfunc_impl = NULL;
111    }
112  }
113
114  PyObject *py_dict = (PyObject *)session_dictionary;
115  if (!PythonDictionary::Check(py_dict))
116    return true;
117
118  PythonDictionary dict(PyRefType::Borrowed, py_dict);
119
120  PyErr_Cleaner pyerr_cleanup(true); // show Python errors
121
122  PythonCallable pfunc(PyRefType::Borrowed, pfunc_impl);
123
124  if (!pfunc.IsAllocated()) {
125    pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
126        python_function_name, dict);
127    if (!pfunc.IsAllocated())
128      return false;
129
130    if (pyfunct_wrapper) {
131      *pyfunct_wrapper = pfunc.get();
132      Py_XINCREF(pfunc.get());
133    }
134  }
135
136  PythonObject result;
137  auto argc = pfunc.GetArgInfo();
138  if (!argc) {
139    llvm::consumeError(argc.takeError());
140    return false;
141  }
142
143  PythonObject value_arg = ToSWIGWrapper(valobj_sp);
144
145  if (argc.get().max_positional_args < 3)
146    result = pfunc(value_arg, dict);
147  else
148    result = pfunc(value_arg, dict, ToSWIGWrapper(*options_sp));
149
150  retval = result.Str().GetString().str();
151
152  return true;
153}
154
155void *lldb_private::LLDBSwigPythonCreateSyntheticProvider(
156    const char *python_class_name, const char *session_dictionary_name,
157    const lldb::ValueObjectSP &valobj_sp) {
158  if (python_class_name == NULL || python_class_name[0] == '\0' ||
159      !session_dictionary_name)
160    Py_RETURN_NONE;
161
162  PyErr_Cleaner py_err_cleaner(true);
163
164  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
165      session_dictionary_name);
166  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
167      python_class_name, dict);
168
169  if (!pfunc.IsAllocated())
170    Py_RETURN_NONE;
171
172  auto sb_value = std::make_unique<lldb::SBValue>(valobj_sp);
173  sb_value->SetPreferSyntheticValue(false);
174
175  PythonObject val_arg = ToSWIGWrapper(std::move(sb_value));
176  if (!val_arg.IsAllocated())
177    Py_RETURN_NONE;
178
179  PythonObject result = pfunc(val_arg, dict);
180
181  if (result.IsAllocated())
182    return result.release();
183
184  Py_RETURN_NONE;
185}
186
187void *lldb_private::LLDBSwigPythonCreateCommandObject(
188    const char *python_class_name, const char *session_dictionary_name,
189    lldb::DebuggerSP debugger_sp) {
190  if (python_class_name == NULL || python_class_name[0] == '\0' ||
191      !session_dictionary_name)
192    Py_RETURN_NONE;
193
194  PyErr_Cleaner py_err_cleaner(true);
195  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
196      session_dictionary_name);
197  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
198      python_class_name, dict);
199
200  if (!pfunc.IsAllocated())
201    return nullptr;
202
203  PythonObject result = pfunc(ToSWIGWrapper(std::move(debugger_sp)), dict);
204
205  if (result.IsAllocated())
206    return result.release();
207
208  Py_RETURN_NONE;
209}
210
211void *lldb_private::LLDBSwigPythonCreateScriptedProcess(
212    const char *python_class_name, const char *session_dictionary_name,
213    const lldb::TargetSP &target_sp,
214    const lldb_private::StructuredDataImpl &args_impl,
215    std::string &error_string) {
216  if (python_class_name == NULL || python_class_name[0] == '\0' ||
217      !session_dictionary_name)
218    Py_RETURN_NONE;
219
220  PyErr_Cleaner py_err_cleaner(true);
221
222  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
223      session_dictionary_name);
224  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
225      python_class_name, dict);
226
227  if (!pfunc.IsAllocated()) {
228    error_string.append("could not find script class: ");
229    error_string.append(python_class_name);
230    return nullptr;
231  }
232
233  PythonObject target_arg = ToSWIGWrapper(target_sp);
234
235  llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
236  if (!arg_info) {
237    llvm::handleAllErrors(
238        arg_info.takeError(),
239        [&](PythonException &E) { error_string.append(E.ReadBacktrace()); },
240        [&](const llvm::ErrorInfoBase &E) {
241          error_string.append(E.message());
242        });
243    Py_RETURN_NONE;
244  }
245
246  PythonObject result = {};
247  if (arg_info.get().max_positional_args == 2) {
248    result = pfunc(target_arg, ToSWIGWrapper(args_impl));
249  } else {
250    error_string.assign("wrong number of arguments in __init__, should be 2 "
251                        "(not including self)");
252    Py_RETURN_NONE;
253  }
254
255  if (result.IsAllocated())
256    return result.release();
257  Py_RETURN_NONE;
258}
259
260void *lldb_private::LLDBSwigPythonCreateScriptedThread(
261    const char *python_class_name, const char *session_dictionary_name,
262    const lldb::ProcessSP &process_sp, const StructuredDataImpl &args_impl,
263    std::string &error_string) {
264  if (python_class_name == NULL || python_class_name[0] == '\0' ||
265      !session_dictionary_name)
266    Py_RETURN_NONE;
267
268  PyErr_Cleaner py_err_cleaner(true);
269
270  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
271      session_dictionary_name);
272  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
273      python_class_name, dict);
274
275  if (!pfunc.IsAllocated()) {
276    error_string.append("could not find script class: ");
277    error_string.append(python_class_name);
278    return nullptr;
279  }
280
281  llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
282  if (!arg_info) {
283    llvm::handleAllErrors(
284        arg_info.takeError(),
285        [&](PythonException &E) { error_string.append(E.ReadBacktrace()); },
286        [&](const llvm::ErrorInfoBase &E) {
287          error_string.append(E.message());
288        });
289    Py_RETURN_NONE;
290  }
291
292  PythonObject result = {};
293  if (arg_info.get().max_positional_args == 2) {
294    result = pfunc(ToSWIGWrapper(process_sp), ToSWIGWrapper(args_impl));
295  } else {
296    error_string.assign("wrong number of arguments in __init__, should be 2 "
297                        "(not including self)");
298    Py_RETURN_NONE;
299  }
300
301  if (result.IsAllocated())
302    return result.release();
303  Py_RETURN_NONE;
304}
305
306void *lldb_private::LLDBSwigPythonCreateScriptedThreadPlan(
307    const char *python_class_name, const char *session_dictionary_name,
308    const lldb_private::StructuredDataImpl &args_impl,
309    std::string &error_string, const lldb::ThreadPlanSP &thread_plan_sp) {
310  if (python_class_name == NULL || python_class_name[0] == '\0' ||
311      !session_dictionary_name)
312    Py_RETURN_NONE;
313
314  PyErr_Cleaner py_err_cleaner(true);
315
316  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
317      session_dictionary_name);
318  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
319      python_class_name, dict);
320
321  if (!pfunc.IsAllocated()) {
322    error_string.append("could not find script class: ");
323    error_string.append(python_class_name);
324    return nullptr;
325  }
326
327  PythonObject tp_arg = ToSWIGWrapper(thread_plan_sp);
328
329  llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
330  if (!arg_info) {
331    llvm::handleAllErrors(
332        arg_info.takeError(),
333        [&](PythonException &E) { error_string.append(E.ReadBacktrace()); },
334        [&](const llvm::ErrorInfoBase &E) {
335          error_string.append(E.message());
336        });
337    Py_RETURN_NONE;
338  }
339
340  PythonObject result = {};
341  auto args_sb = std::make_unique<lldb::SBStructuredData>(args_impl);
342  if (arg_info.get().max_positional_args == 2) {
343    if (args_sb->IsValid()) {
344      error_string.assign(
345          "args passed, but __init__ does not take an args dictionary");
346      Py_RETURN_NONE;
347    }
348    result = pfunc(tp_arg, dict);
349  } else if (arg_info.get().max_positional_args >= 3) {
350    result = pfunc(tp_arg, ToSWIGWrapper(std::move(args_sb)), dict);
351  } else {
352    error_string.assign("wrong number of arguments in __init__, should be 2 or "
353                        "3 (not including self)");
354    Py_RETURN_NONE;
355  }
356
357  // FIXME: At this point we should check that the class we found supports all
358  // the methods that we need.
359
360  if (result.IsAllocated())
361    return result.release();
362  Py_RETURN_NONE;
363}
364
365bool lldb_private::LLDBSWIGPythonCallThreadPlan(
366    void *implementor, const char *method_name, lldb_private::Event *event,
367    bool &got_error) {
368  got_error = false;
369
370  PyErr_Cleaner py_err_cleaner(false);
371  PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
372  auto pfunc = self.ResolveName<PythonCallable>(method_name);
373
374  if (!pfunc.IsAllocated())
375    return false;
376
377  PythonObject result;
378  if (event != nullptr) {
379    ScopedPythonObject<SBEvent> event_arg = ToSWIGWrapper(event);
380    result = pfunc(event_arg.obj());
381  } else
382    result = pfunc();
383
384  if (PyErr_Occurred()) {
385    got_error = true;
386    printf("Return value was neither false nor true for call to %s.\n",
387           method_name);
388    PyErr_Print();
389    return false;
390  }
391
392  if (result.get() == Py_True)
393    return true;
394  else if (result.get() == Py_False)
395    return false;
396
397  // Somebody returned the wrong thing...
398  got_error = true;
399  printf("Wrong return value type for call to %s.\n", method_name);
400  return false;
401}
402
403void *lldb_private::LLDBSwigPythonCreateScriptedBreakpointResolver(
404    const char *python_class_name, const char *session_dictionary_name,
405    const StructuredDataImpl &args_impl,
406    const lldb::BreakpointSP &breakpoint_sp) {
407
408  if (python_class_name == NULL || python_class_name[0] == '\0' ||
409      !session_dictionary_name)
410    Py_RETURN_NONE;
411
412  PyErr_Cleaner py_err_cleaner(true);
413
414  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
415      session_dictionary_name);
416  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
417      python_class_name, dict);
418
419  if (!pfunc.IsAllocated())
420    return nullptr;
421
422  PythonObject result =
423      pfunc(ToSWIGWrapper(breakpoint_sp), ToSWIGWrapper(args_impl), dict);
424  // FIXME: At this point we should check that the class we found supports all
425  // the methods that we need.
426
427  if (result.IsAllocated()) {
428    // Check that __callback__ is defined:
429    auto callback_func = result.ResolveName<PythonCallable>("__callback__");
430    if (callback_func.IsAllocated())
431      return result.release();
432    else
433      result.release();
434  }
435  Py_RETURN_NONE;
436}
437
438unsigned int lldb_private::LLDBSwigPythonCallBreakpointResolver(
439    void *implementor, const char *method_name,
440    lldb_private::SymbolContext *sym_ctx) {
441  PyErr_Cleaner py_err_cleaner(false);
442  PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
443  auto pfunc = self.ResolveName<PythonCallable>(method_name);
444
445  if (!pfunc.IsAllocated())
446    return 0;
447
448  PythonObject result = sym_ctx ? pfunc(ToSWIGWrapper(*sym_ctx)) : pfunc();
449
450  if (PyErr_Occurred()) {
451    PyErr_Print();
452    PyErr_Clear();
453    return 0;
454  }
455
456  // The callback will return a bool, but we're need to also return ints
457  // so we're squirrelling the bool through as an int...  And if you return
458  // nothing, we'll continue.
459  if (strcmp(method_name, "__callback__") == 0) {
460    if (result.get() == Py_False)
461      return 0;
462    else
463      return 1;
464  }
465
466  long long ret_val = unwrapOrSetPythonException(As<long long>(result));
467
468  if (PyErr_Occurred()) {
469    PyErr_Print();
470    PyErr_Clear();
471    return 0;
472  }
473
474  return ret_val;
475}
476
477void *lldb_private::LLDBSwigPythonCreateScriptedStopHook(
478    lldb::TargetSP target_sp, const char *python_class_name,
479    const char *session_dictionary_name, const StructuredDataImpl &args_impl,
480    Status &error) {
481  if (python_class_name == NULL || python_class_name[0] == '\0') {
482    error.SetErrorString("Empty class name.");
483    Py_RETURN_NONE;
484  }
485  if (!session_dictionary_name) {
486    error.SetErrorString("No session dictionary");
487    Py_RETURN_NONE;
488  }
489
490  PyErr_Cleaner py_err_cleaner(true);
491
492  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
493      session_dictionary_name);
494  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
495      python_class_name, dict);
496
497  if (!pfunc.IsAllocated()) {
498    error.SetErrorStringWithFormat("Could not find class: %s.",
499                                   python_class_name);
500    return nullptr;
501  }
502
503  PythonObject result =
504      pfunc(ToSWIGWrapper(target_sp), ToSWIGWrapper(args_impl), dict);
505
506  if (result.IsAllocated()) {
507    // Check that the handle_stop callback is defined:
508    auto callback_func = result.ResolveName<PythonCallable>("handle_stop");
509    if (callback_func.IsAllocated()) {
510      if (auto args_info = callback_func.GetArgInfo()) {
511        size_t num_args = (*args_info).max_positional_args;
512        if (num_args != 2) {
513          error.SetErrorStringWithFormat(
514              "Wrong number of args for "
515              "handle_stop callback, should be 2 (excluding self), got: %zu",
516              num_args);
517          Py_RETURN_NONE;
518        } else
519          return result.release();
520      } else {
521        error.SetErrorString("Couldn't get num arguments for handle_stop "
522                             "callback.");
523        Py_RETURN_NONE;
524      }
525      return result.release();
526    } else {
527      error.SetErrorStringWithFormat("Class \"%s\" is missing the required "
528                                     "handle_stop callback.",
529                                     python_class_name);
530      result.release();
531    }
532  }
533  Py_RETURN_NONE;
534}
535
536bool lldb_private::LLDBSwigPythonStopHookCallHandleStop(
537    void *implementor, lldb::ExecutionContextRefSP exc_ctx_sp,
538    lldb::StreamSP stream) {
539  // handle_stop will return a bool with the meaning "should_stop"...
540  // If you return nothing we'll assume we are going to stop.
541  // Also any errors should return true, since we should stop on error.
542
543  PyErr_Cleaner py_err_cleaner(false);
544  PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
545  auto pfunc = self.ResolveName<PythonCallable>("handle_stop");
546
547  if (!pfunc.IsAllocated())
548    return true;
549
550  auto *sb_stream = new lldb::SBStream();
551  PythonObject sb_stream_arg =
552      ToSWIGWrapper(std::unique_ptr<lldb::SBStream>(sb_stream));
553  PythonObject result =
554      pfunc(ToSWIGWrapper(std::move(exc_ctx_sp)), sb_stream_arg);
555
556  if (PyErr_Occurred()) {
557    stream->PutCString("Python error occurred handling stop-hook.");
558    PyErr_Print();
559    PyErr_Clear();
560    return true;
561  }
562
563  // Now add the result to the output stream.  SBStream only
564  // makes an internally help StreamString which I can't interpose, so I
565  // have to copy it over here.
566  stream->PutCString(sb_stream->GetData());
567
568  if (result.get() == Py_False)
569    return false;
570  else
571    return true;
572}
573
574// wrapper that calls an optional instance member of an object taking no
575// arguments
576static PyObject *LLDBSwigPython_CallOptionalMember(
577    PyObject * implementor, char *callee_name,
578    PyObject *ret_if_not_found = Py_None, bool *was_found = NULL) {
579  PyErr_Cleaner py_err_cleaner(false);
580
581  PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
582  auto pfunc = self.ResolveName<PythonCallable>(callee_name);
583
584  if (!pfunc.IsAllocated()) {
585    if (was_found)
586      *was_found = false;
587    Py_XINCREF(ret_if_not_found);
588    return ret_if_not_found;
589  }
590
591  if (was_found)
592    *was_found = true;
593
594  PythonObject result = pfunc();
595  return result.release();
596}
597
598size_t lldb_private::LLDBSwigPython_CalculateNumChildren(PyObject * implementor,
599                                                         uint32_t max) {
600  PythonObject self(PyRefType::Borrowed, implementor);
601  auto pfunc = self.ResolveName<PythonCallable>("num_children");
602
603  if (!pfunc.IsAllocated())
604    return 0;
605
606  auto arg_info = pfunc.GetArgInfo();
607  if (!arg_info) {
608    llvm::consumeError(arg_info.takeError());
609    return 0;
610  }
611
612  size_t ret_val;
613  if (arg_info.get().max_positional_args < 1)
614    ret_val = unwrapOrSetPythonException(As<long long>(pfunc.Call()));
615  else
616    ret_val = unwrapOrSetPythonException(
617        As<long long>(pfunc.Call(PythonInteger(max))));
618
619  if (PyErr_Occurred()) {
620    PyErr_Print();
621    PyErr_Clear();
622    return 0;
623  }
624
625  if (arg_info.get().max_positional_args < 1)
626    ret_val = std::min(ret_val, static_cast<size_t>(max));
627
628  return ret_val;
629}
630
631PyObject *lldb_private::LLDBSwigPython_GetChildAtIndex(PyObject * implementor,
632                                                       uint32_t idx) {
633  PyErr_Cleaner py_err_cleaner(true);
634
635  PythonObject self(PyRefType::Borrowed, implementor);
636  auto pfunc = self.ResolveName<PythonCallable>("get_child_at_index");
637
638  if (!pfunc.IsAllocated())
639    return nullptr;
640
641  PythonObject result = pfunc(PythonInteger(idx));
642
643  if (!result.IsAllocated())
644    return nullptr;
645
646  lldb::SBValue *sbvalue_ptr = nullptr;
647  if (SWIG_ConvertPtr(result.get(), (void **)&sbvalue_ptr,
648                      SWIGTYPE_p_lldb__SBValue, 0) == -1)
649    return nullptr;
650
651  if (sbvalue_ptr == nullptr)
652    return nullptr;
653
654  return result.release();
655}
656
657int lldb_private::LLDBSwigPython_GetIndexOfChildWithName(
658    PyObject * implementor, const char *child_name) {
659  PyErr_Cleaner py_err_cleaner(true);
660
661  PythonObject self(PyRefType::Borrowed, implementor);
662  auto pfunc = self.ResolveName<PythonCallable>("get_child_index");
663
664  if (!pfunc.IsAllocated())
665    return UINT32_MAX;
666
667  llvm::Expected<PythonObject> result = pfunc.Call(PythonString(child_name));
668
669  long long retval =
670      unwrapOrSetPythonException(As<long long>(std::move(result)));
671
672  if (PyErr_Occurred()) {
673    PyErr_Clear(); // FIXME print this? do something else
674    return UINT32_MAX;
675  }
676
677  if (retval >= 0)
678    return (uint32_t)retval;
679
680  return UINT32_MAX;
681}
682
683bool lldb_private::LLDBSwigPython_UpdateSynthProviderInstance(PyObject *
684                                                              implementor) {
685  bool ret_val = false;
686
687  static char callee_name[] = "update";
688
689  PyObject *py_return =
690      LLDBSwigPython_CallOptionalMember(implementor, callee_name);
691
692  if (py_return == Py_True)
693    ret_val = true;
694
695  Py_XDECREF(py_return);
696
697  return ret_val;
698}
699
700bool lldb_private::LLDBSwigPython_MightHaveChildrenSynthProviderInstance(
701    PyObject * implementor) {
702  bool ret_val = false;
703
704  static char callee_name[] = "has_children";
705
706  PyObject *py_return =
707      LLDBSwigPython_CallOptionalMember(implementor, callee_name, Py_True);
708
709  if (py_return == Py_True)
710    ret_val = true;
711
712  Py_XDECREF(py_return);
713
714  return ret_val;
715}
716
717PyObject *lldb_private::LLDBSwigPython_GetValueSynthProviderInstance(
718    PyObject * implementor) {
719  PyObject *ret_val = nullptr;
720
721  static char callee_name[] = "get_value";
722
723  PyObject *py_return =
724      LLDBSwigPython_CallOptionalMember(implementor, callee_name, Py_None);
725
726  if (py_return == Py_None || py_return == nullptr)
727    ret_val = nullptr;
728
729  lldb::SBValue *sbvalue_ptr = NULL;
730
731  if (SWIG_ConvertPtr(py_return, (void **)&sbvalue_ptr,
732                      SWIGTYPE_p_lldb__SBValue, 0) == -1)
733    ret_val = nullptr;
734  else if (sbvalue_ptr == NULL)
735    ret_val = nullptr;
736  else
737    ret_val = py_return;
738
739  Py_XDECREF(py_return);
740  return ret_val;
741}
742
743void *lldb_private::LLDBSWIGPython_CastPyObjectToSBData(PyObject * data) {
744  lldb::SBData *sb_ptr = nullptr;
745
746  int valid_cast =
747      SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBData, 0);
748
749  if (valid_cast == -1)
750    return NULL;
751
752  return sb_ptr;
753}
754
755void *lldb_private::LLDBSWIGPython_CastPyObjectToSBError(PyObject * data) {
756  lldb::SBError *sb_ptr = nullptr;
757
758  int valid_cast =
759      SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBError, 0);
760
761  if (valid_cast == -1)
762    return NULL;
763
764  return sb_ptr;
765}
766
767void *lldb_private::LLDBSWIGPython_CastPyObjectToSBValue(PyObject * data) {
768  lldb::SBValue *sb_ptr = NULL;
769
770  int valid_cast =
771      SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBValue, 0);
772
773  if (valid_cast == -1)
774    return NULL;
775
776  return sb_ptr;
777}
778
779void *lldb_private::LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *
780                                                                    data) {
781  lldb::SBMemoryRegionInfo *sb_ptr = NULL;
782
783  int valid_cast = SWIG_ConvertPtr(data, (void **)&sb_ptr,
784                                   SWIGTYPE_p_lldb__SBMemoryRegionInfo, 0);
785
786  if (valid_cast == -1)
787    return NULL;
788
789  return sb_ptr;
790}
791
792bool lldb_private::LLDBSwigPythonCallCommand(
793    const char *python_function_name, const char *session_dictionary_name,
794    lldb::DebuggerSP debugger, const char *args,
795    lldb_private::CommandReturnObject &cmd_retobj,
796    lldb::ExecutionContextRefSP exe_ctx_ref_sp) {
797
798  PyErr_Cleaner py_err_cleaner(true);
799  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
800      session_dictionary_name);
801  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
802      python_function_name, dict);
803
804  if (!pfunc.IsAllocated())
805    return false;
806
807  auto argc = pfunc.GetArgInfo();
808  if (!argc) {
809    llvm::consumeError(argc.takeError());
810    return false;
811  }
812  PythonObject debugger_arg = ToSWIGWrapper(std::move(debugger));
813  auto cmd_retobj_arg = ToSWIGWrapper(cmd_retobj);
814
815  if (argc.get().max_positional_args < 5u)
816    pfunc(debugger_arg, PythonString(args), cmd_retobj_arg.obj(), dict);
817  else
818    pfunc(debugger_arg, PythonString(args),
819          ToSWIGWrapper(std::move(exe_ctx_ref_sp)), cmd_retobj_arg.obj(), dict);
820
821  return true;
822}
823
824bool lldb_private::LLDBSwigPythonCallCommandObject(
825    PyObject *implementor, lldb::DebuggerSP debugger, const char *args,
826    lldb_private::CommandReturnObject &cmd_retobj,
827    lldb::ExecutionContextRefSP exe_ctx_ref_sp) {
828
829  PyErr_Cleaner py_err_cleaner(true);
830
831  PythonObject self(PyRefType::Borrowed, implementor);
832  auto pfunc = self.ResolveName<PythonCallable>("__call__");
833
834  if (!pfunc.IsAllocated())
835    return false;
836
837  auto cmd_retobj_arg = ToSWIGWrapper(cmd_retobj);
838
839  pfunc(ToSWIGWrapper(std::move(debugger)), PythonString(args),
840        ToSWIGWrapper(exe_ctx_ref_sp), cmd_retobj_arg.obj());
841
842  return true;
843}
844
845void *lldb_private::LLDBSWIGPythonCreateOSPlugin(
846    const char *python_class_name, const char *session_dictionary_name,
847    const lldb::ProcessSP &process_sp) {
848  if (python_class_name == NULL || python_class_name[0] == '\0' ||
849      !session_dictionary_name)
850    Py_RETURN_NONE;
851
852  PyErr_Cleaner py_err_cleaner(true);
853
854  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
855      session_dictionary_name);
856  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
857      python_class_name, dict);
858
859  if (!pfunc.IsAllocated())
860    Py_RETURN_NONE;
861
862  auto result = pfunc(ToSWIGWrapper(process_sp));
863
864  if (result.IsAllocated())
865    return result.release();
866
867  Py_RETURN_NONE;
868}
869
870void *lldb_private::LLDBSWIGPython_CreateFrameRecognizer(
871    const char *python_class_name, const char *session_dictionary_name) {
872  if (python_class_name == NULL || python_class_name[0] == '\0' ||
873      !session_dictionary_name)
874    Py_RETURN_NONE;
875
876  PyErr_Cleaner py_err_cleaner(true);
877
878  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
879      session_dictionary_name);
880  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
881      python_class_name, dict);
882
883  if (!pfunc.IsAllocated())
884    Py_RETURN_NONE;
885
886  auto result = pfunc();
887
888  if (result.IsAllocated())
889    return result.release();
890
891  Py_RETURN_NONE;
892}
893
894PyObject *lldb_private::LLDBSwigPython_GetRecognizedArguments(
895    PyObject * implementor, const lldb::StackFrameSP &frame_sp) {
896  static char callee_name[] = "get_recognized_arguments";
897
898  PythonObject arg = ToSWIGWrapper(frame_sp);
899
900  PythonString str(callee_name);
901  PyObject *result =
902      PyObject_CallMethodObjArgs(implementor, str.get(), arg.get(), NULL);
903  return result;
904}
905
906void *lldb_private::LLDBSWIGPython_GetDynamicSetting(
907    void *module, const char *setting, const lldb::TargetSP &target_sp) {
908  if (!module || !setting)
909    Py_RETURN_NONE;
910
911  PyErr_Cleaner py_err_cleaner(true);
912  PythonObject py_module(PyRefType::Borrowed, (PyObject *)module);
913  auto pfunc = py_module.ResolveName<PythonCallable>("get_dynamic_setting");
914
915  if (!pfunc.IsAllocated())
916    Py_RETURN_NONE;
917
918  auto result = pfunc(ToSWIGWrapper(target_sp), PythonString(setting));
919
920  return result.release();
921}
922
923bool lldb_private::LLDBSWIGPythonRunScriptKeywordProcess(
924    const char *python_function_name, const char *session_dictionary_name,
925    const lldb::ProcessSP &process, std::string &output) {
926
927  if (python_function_name == NULL || python_function_name[0] == '\0' ||
928      !session_dictionary_name)
929    return false;
930
931  PyErr_Cleaner py_err_cleaner(true);
932
933  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
934      session_dictionary_name);
935  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
936      python_function_name, dict);
937
938  if (!pfunc.IsAllocated())
939    return false;
940
941  auto result = pfunc(ToSWIGWrapper(process), dict);
942
943  output = result.Str().GetString().str();
944
945  return true;
946}
947
948llvm::Optional<std::string> lldb_private::LLDBSWIGPythonRunScriptKeywordThread(
949    const char *python_function_name, const char *session_dictionary_name,
950    lldb::ThreadSP thread) {
951  if (python_function_name == NULL || python_function_name[0] == '\0' ||
952      !session_dictionary_name)
953    return llvm::None;
954
955  PyErr_Cleaner py_err_cleaner(true);
956
957  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
958      session_dictionary_name);
959  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
960      python_function_name, dict);
961
962  if (!pfunc.IsAllocated())
963    return llvm::None;
964
965  auto result = pfunc(ToSWIGWrapper(std::move(thread)), dict);
966
967  return result.Str().GetString().str();
968}
969
970bool lldb_private::LLDBSWIGPythonRunScriptKeywordTarget(
971    const char *python_function_name, const char *session_dictionary_name,
972    const lldb::TargetSP &target, std::string &output) {
973
974  if (python_function_name == NULL || python_function_name[0] == '\0' ||
975      !session_dictionary_name)
976    return false;
977
978  PyErr_Cleaner py_err_cleaner(true);
979
980  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
981      session_dictionary_name);
982  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
983      python_function_name, dict);
984
985  if (!pfunc.IsAllocated())
986    return false;
987
988  auto result = pfunc(ToSWIGWrapper(target), dict);
989
990  output = result.Str().GetString().str();
991
992  return true;
993}
994
995llvm::Optional<std::string> lldb_private::LLDBSWIGPythonRunScriptKeywordFrame(
996    const char *python_function_name, const char *session_dictionary_name,
997    lldb::StackFrameSP frame) {
998  if (python_function_name == NULL || python_function_name[0] == '\0' ||
999      !session_dictionary_name)
1000    return llvm::None;
1001
1002  PyErr_Cleaner py_err_cleaner(true);
1003
1004  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
1005      session_dictionary_name);
1006  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
1007      python_function_name, dict);
1008
1009  if (!pfunc.IsAllocated())
1010    return llvm::None;
1011
1012  auto result = pfunc(ToSWIGWrapper(std::move(frame)), dict);
1013
1014  return result.Str().GetString().str();
1015}
1016
1017bool lldb_private::LLDBSWIGPythonRunScriptKeywordValue(
1018    const char *python_function_name, const char *session_dictionary_name,
1019    const lldb::ValueObjectSP &value, std::string &output) {
1020
1021  if (python_function_name == NULL || python_function_name[0] == '\0' ||
1022      !session_dictionary_name)
1023    return false;
1024
1025  PyErr_Cleaner py_err_cleaner(true);
1026
1027  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
1028      session_dictionary_name);
1029  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
1030      python_function_name, dict);
1031
1032  if (!pfunc.IsAllocated())
1033    return false;
1034
1035  auto result = pfunc(ToSWIGWrapper(value), dict);
1036
1037  output = result.Str().GetString().str();
1038
1039  return true;
1040}
1041
1042bool lldb_private::LLDBSwigPythonCallModuleInit(
1043    const char *python_module_name, const char *session_dictionary_name,
1044    lldb::DebuggerSP debugger) {
1045  std::string python_function_name_string = python_module_name;
1046  python_function_name_string += ".__lldb_init_module";
1047  const char *python_function_name = python_function_name_string.c_str();
1048
1049  PyErr_Cleaner py_err_cleaner(true);
1050
1051  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
1052      session_dictionary_name);
1053  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
1054      python_function_name, dict);
1055
1056  // This method is optional and need not exist.  So if we don't find it,
1057  // it's actually a success, not a failure.
1058  if (!pfunc.IsAllocated())
1059    return true;
1060
1061  pfunc(ToSWIGWrapper(std::move(debugger)), dict);
1062
1063  return true;
1064}
1065
1066lldb::ValueObjectSP lldb_private::LLDBSWIGPython_GetValueObjectSPFromSBValue(
1067    void *data) {
1068  lldb::ValueObjectSP valobj_sp;
1069  if (data) {
1070    lldb::SBValue *sb_ptr = (lldb::SBValue *)data;
1071    valobj_sp = sb_ptr->GetSP();
1072  }
1073  return valobj_sp;
1074}
1075
1076// For the LogOutputCallback functions
1077static void LLDBSwigPythonCallPythonLogOutputCallback(const char *str,
1078                                                      void *baton) {
1079  if (baton != Py_None) {
1080    SWIG_PYTHON_THREAD_BEGIN_BLOCK;
1081    PyObject *result = PyObject_CallFunction(
1082        reinterpret_cast<PyObject *>(baton), const_cast<char *>("s"), str);
1083    Py_XDECREF(result);
1084    SWIG_PYTHON_THREAD_END_BLOCK;
1085  }
1086}
1087%}
1088