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    lldb::SBEvent sb_event(event);
380    PythonObject event_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_event));
381    result = pfunc(event_arg);
382  } else
383    result = pfunc();
384
385  if (PyErr_Occurred()) {
386    got_error = true;
387    printf("Return value was neither false nor true for call to %s.\n",
388           method_name);
389    PyErr_Print();
390    return false;
391  }
392
393  if (result.get() == Py_True)
394    return true;
395  else if (result.get() == Py_False)
396    return false;
397
398  // Somebody returned the wrong thing...
399  got_error = true;
400  printf("Wrong return value type for call to %s.\n", method_name);
401  return false;
402}
403
404void *lldb_private::LLDBSwigPythonCreateScriptedBreakpointResolver(
405    const char *python_class_name, const char *session_dictionary_name,
406    const StructuredDataImpl &args_impl,
407    const lldb::BreakpointSP &breakpoint_sp) {
408
409  if (python_class_name == NULL || python_class_name[0] == '\0' ||
410      !session_dictionary_name)
411    Py_RETURN_NONE;
412
413  PyErr_Cleaner py_err_cleaner(true);
414
415  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
416      session_dictionary_name);
417  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
418      python_class_name, dict);
419
420  if (!pfunc.IsAllocated())
421    return nullptr;
422
423  PythonObject result =
424      pfunc(ToSWIGWrapper(breakpoint_sp), ToSWIGWrapper(args_impl), dict);
425  // FIXME: At this point we should check that the class we found supports all
426  // the methods that we need.
427
428  if (result.IsAllocated()) {
429    // Check that __callback__ is defined:
430    auto callback_func = result.ResolveName<PythonCallable>("__callback__");
431    if (callback_func.IsAllocated())
432      return result.release();
433    else
434      result.release();
435  }
436  Py_RETURN_NONE;
437}
438
439unsigned int lldb_private::LLDBSwigPythonCallBreakpointResolver(
440    void *implementor, const char *method_name,
441    lldb_private::SymbolContext *sym_ctx) {
442  PyErr_Cleaner py_err_cleaner(false);
443  PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
444  auto pfunc = self.ResolveName<PythonCallable>(method_name);
445
446  if (!pfunc.IsAllocated())
447    return 0;
448
449  PythonObject result = sym_ctx ? pfunc(ToSWIGWrapper(*sym_ctx)) : pfunc();
450
451  if (PyErr_Occurred()) {
452    PyErr_Print();
453    PyErr_Clear();
454    return 0;
455  }
456
457  // The callback will return a bool, but we're need to also return ints
458  // so we're squirrelling the bool through as an int...  And if you return
459  // nothing, we'll continue.
460  if (strcmp(method_name, "__callback__") == 0) {
461    if (result.get() == Py_False)
462      return 0;
463    else
464      return 1;
465  }
466
467  long long ret_val = unwrapOrSetPythonException(As<long long>(result));
468
469  if (PyErr_Occurred()) {
470    PyErr_Print();
471    PyErr_Clear();
472    return 0;
473  }
474
475  return ret_val;
476}
477
478void *lldb_private::LLDBSwigPythonCreateScriptedStopHook(
479    lldb::TargetSP target_sp, const char *python_class_name,
480    const char *session_dictionary_name, const StructuredDataImpl &args_impl,
481    Status &error) {
482  if (python_class_name == NULL || python_class_name[0] == '\0') {
483    error.SetErrorString("Empty class name.");
484    Py_RETURN_NONE;
485  }
486  if (!session_dictionary_name) {
487    error.SetErrorString("No session dictionary");
488    Py_RETURN_NONE;
489  }
490
491  PyErr_Cleaner py_err_cleaner(true);
492
493  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
494      session_dictionary_name);
495  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
496      python_class_name, dict);
497
498  if (!pfunc.IsAllocated()) {
499    error.SetErrorStringWithFormat("Could not find class: %s.",
500                                   python_class_name);
501    return nullptr;
502  }
503
504  PythonObject result =
505      pfunc(ToSWIGWrapper(target_sp), ToSWIGWrapper(args_impl), dict);
506
507  if (result.IsAllocated()) {
508    // Check that the handle_stop callback is defined:
509    auto callback_func = result.ResolveName<PythonCallable>("handle_stop");
510    if (callback_func.IsAllocated()) {
511      if (auto args_info = callback_func.GetArgInfo()) {
512        size_t num_args = (*args_info).max_positional_args;
513        if (num_args != 2) {
514          error.SetErrorStringWithFormat(
515              "Wrong number of args for "
516              "handle_stop callback, should be 2 (excluding self), got: %zu",
517              num_args);
518          Py_RETURN_NONE;
519        } else
520          return result.release();
521      } else {
522        error.SetErrorString("Couldn't get num arguments for handle_stop "
523                             "callback.");
524        Py_RETURN_NONE;
525      }
526      return result.release();
527    } else {
528      error.SetErrorStringWithFormat("Class \"%s\" is missing the required "
529                                     "handle_stop callback.",
530                                     python_class_name);
531      result.release();
532    }
533  }
534  Py_RETURN_NONE;
535}
536
537bool lldb_private::LLDBSwigPythonStopHookCallHandleStop(
538    void *implementor, lldb::ExecutionContextRefSP exc_ctx_sp,
539    lldb::StreamSP stream) {
540  // handle_stop will return a bool with the meaning "should_stop"...
541  // If you return nothing we'll assume we are going to stop.
542  // Also any errors should return true, since we should stop on error.
543
544  PyErr_Cleaner py_err_cleaner(false);
545  PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
546  auto pfunc = self.ResolveName<PythonCallable>("handle_stop");
547
548  if (!pfunc.IsAllocated())
549    return true;
550
551  auto *sb_stream = new lldb::SBStream();
552  PythonObject sb_stream_arg =
553      ToSWIGWrapper(std::unique_ptr<lldb::SBStream>(sb_stream));
554  PythonObject result =
555      pfunc(ToSWIGWrapper(std::move(exc_ctx_sp)), sb_stream_arg);
556
557  if (PyErr_Occurred()) {
558    stream->PutCString("Python error occurred handling stop-hook.");
559    PyErr_Print();
560    PyErr_Clear();
561    return true;
562  }
563
564  // Now add the result to the output stream.  SBStream only
565  // makes an internally help StreamString which I can't interpose, so I
566  // have to copy it over here.
567  stream->PutCString(sb_stream->GetData());
568
569  if (result.get() == Py_False)
570    return false;
571  else
572    return true;
573}
574
575// wrapper that calls an optional instance member of an object taking no
576// arguments
577static PyObject *LLDBSwigPython_CallOptionalMember(
578    PyObject * implementor, char *callee_name,
579    PyObject *ret_if_not_found = Py_None, bool *was_found = NULL) {
580  PyErr_Cleaner py_err_cleaner(false);
581
582  PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
583  auto pfunc = self.ResolveName<PythonCallable>(callee_name);
584
585  if (!pfunc.IsAllocated()) {
586    if (was_found)
587      *was_found = false;
588    Py_XINCREF(ret_if_not_found);
589    return ret_if_not_found;
590  }
591
592  if (was_found)
593    *was_found = true;
594
595  PythonObject result = pfunc();
596  return result.release();
597}
598
599size_t lldb_private::LLDBSwigPython_CalculateNumChildren(PyObject * implementor,
600                                                         uint32_t max) {
601  PythonObject self(PyRefType::Borrowed, implementor);
602  auto pfunc = self.ResolveName<PythonCallable>("num_children");
603
604  if (!pfunc.IsAllocated())
605    return 0;
606
607  auto arg_info = pfunc.GetArgInfo();
608  if (!arg_info) {
609    llvm::consumeError(arg_info.takeError());
610    return 0;
611  }
612
613  size_t ret_val;
614  if (arg_info.get().max_positional_args < 1)
615    ret_val = unwrapOrSetPythonException(As<long long>(pfunc.Call()));
616  else
617    ret_val = unwrapOrSetPythonException(
618        As<long long>(pfunc.Call(PythonInteger(max))));
619
620  if (PyErr_Occurred()) {
621    PyErr_Print();
622    PyErr_Clear();
623    return 0;
624  }
625
626  if (arg_info.get().max_positional_args < 1)
627    ret_val = std::min(ret_val, static_cast<size_t>(max));
628
629  return ret_val;
630}
631
632PyObject *lldb_private::LLDBSwigPython_GetChildAtIndex(PyObject * implementor,
633                                                       uint32_t idx) {
634  PyErr_Cleaner py_err_cleaner(true);
635
636  PythonObject self(PyRefType::Borrowed, implementor);
637  auto pfunc = self.ResolveName<PythonCallable>("get_child_at_index");
638
639  if (!pfunc.IsAllocated())
640    return nullptr;
641
642  PythonObject result = pfunc(PythonInteger(idx));
643
644  if (!result.IsAllocated())
645    return nullptr;
646
647  lldb::SBValue *sbvalue_ptr = nullptr;
648  if (SWIG_ConvertPtr(result.get(), (void **)&sbvalue_ptr,
649                      SWIGTYPE_p_lldb__SBValue, 0) == -1)
650    return nullptr;
651
652  if (sbvalue_ptr == nullptr)
653    return nullptr;
654
655  return result.release();
656}
657
658int lldb_private::LLDBSwigPython_GetIndexOfChildWithName(
659    PyObject * implementor, const char *child_name) {
660  PyErr_Cleaner py_err_cleaner(true);
661
662  PythonObject self(PyRefType::Borrowed, implementor);
663  auto pfunc = self.ResolveName<PythonCallable>("get_child_index");
664
665  if (!pfunc.IsAllocated())
666    return UINT32_MAX;
667
668  llvm::Expected<PythonObject> result = pfunc.Call(PythonString(child_name));
669
670  long long retval =
671      unwrapOrSetPythonException(As<long long>(std::move(result)));
672
673  if (PyErr_Occurred()) {
674    PyErr_Clear(); // FIXME print this? do something else
675    return UINT32_MAX;
676  }
677
678  if (retval >= 0)
679    return (uint32_t)retval;
680
681  return UINT32_MAX;
682}
683
684bool lldb_private::LLDBSwigPython_UpdateSynthProviderInstance(PyObject *
685                                                              implementor) {
686  bool ret_val = false;
687
688  static char callee_name[] = "update";
689
690  PyObject *py_return =
691      LLDBSwigPython_CallOptionalMember(implementor, callee_name);
692
693  if (py_return == Py_True)
694    ret_val = true;
695
696  Py_XDECREF(py_return);
697
698  return ret_val;
699}
700
701bool lldb_private::LLDBSwigPython_MightHaveChildrenSynthProviderInstance(
702    PyObject * implementor) {
703  bool ret_val = false;
704
705  static char callee_name[] = "has_children";
706
707  PyObject *py_return =
708      LLDBSwigPython_CallOptionalMember(implementor, callee_name, Py_True);
709
710  if (py_return == Py_True)
711    ret_val = true;
712
713  Py_XDECREF(py_return);
714
715  return ret_val;
716}
717
718PyObject *lldb_private::LLDBSwigPython_GetValueSynthProviderInstance(
719    PyObject * implementor) {
720  PyObject *ret_val = nullptr;
721
722  static char callee_name[] = "get_value";
723
724  PyObject *py_return =
725      LLDBSwigPython_CallOptionalMember(implementor, callee_name, Py_None);
726
727  if (py_return == Py_None || py_return == nullptr)
728    ret_val = nullptr;
729
730  lldb::SBValue *sbvalue_ptr = NULL;
731
732  if (SWIG_ConvertPtr(py_return, (void **)&sbvalue_ptr,
733                      SWIGTYPE_p_lldb__SBValue, 0) == -1)
734    ret_val = nullptr;
735  else if (sbvalue_ptr == NULL)
736    ret_val = nullptr;
737  else
738    ret_val = py_return;
739
740  Py_XDECREF(py_return);
741  return ret_val;
742}
743
744void *lldb_private::LLDBSWIGPython_CastPyObjectToSBData(PyObject * data) {
745  lldb::SBData *sb_ptr = nullptr;
746
747  int valid_cast =
748      SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBData, 0);
749
750  if (valid_cast == -1)
751    return NULL;
752
753  return sb_ptr;
754}
755
756void *lldb_private::LLDBSWIGPython_CastPyObjectToSBError(PyObject * data) {
757  lldb::SBError *sb_ptr = nullptr;
758
759  int valid_cast =
760      SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBError, 0);
761
762  if (valid_cast == -1)
763    return NULL;
764
765  return sb_ptr;
766}
767
768void *lldb_private::LLDBSWIGPython_CastPyObjectToSBValue(PyObject * data) {
769  lldb::SBValue *sb_ptr = NULL;
770
771  int valid_cast =
772      SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBValue, 0);
773
774  if (valid_cast == -1)
775    return NULL;
776
777  return sb_ptr;
778}
779
780void *lldb_private::LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *
781                                                                    data) {
782  lldb::SBMemoryRegionInfo *sb_ptr = NULL;
783
784  int valid_cast = SWIG_ConvertPtr(data, (void **)&sb_ptr,
785                                   SWIGTYPE_p_lldb__SBMemoryRegionInfo, 0);
786
787  if (valid_cast == -1)
788    return NULL;
789
790  return sb_ptr;
791}
792
793bool lldb_private::LLDBSwigPythonCallCommand(
794    const char *python_function_name, const char *session_dictionary_name,
795    lldb::DebuggerSP debugger, const char *args,
796    lldb_private::CommandReturnObject &cmd_retobj,
797    lldb::ExecutionContextRefSP exe_ctx_ref_sp) {
798  lldb::SBCommandReturnObject cmd_retobj_sb(cmd_retobj);
799
800  PyErr_Cleaner py_err_cleaner(true);
801  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
802      session_dictionary_name);
803  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
804      python_function_name, dict);
805
806  if (!pfunc.IsAllocated())
807    return false;
808
809  auto argc = pfunc.GetArgInfo();
810  if (!argc) {
811    llvm::consumeError(argc.takeError());
812    return false;
813  }
814  PythonObject debugger_arg = ToSWIGWrapper(std::move(debugger));
815  PythonObject cmd_retobj_arg(PyRefType::Owned,
816                              SBTypeToSWIGWrapper(cmd_retobj_sb));
817
818  if (argc.get().max_positional_args < 5u)
819    pfunc(debugger_arg, PythonString(args), cmd_retobj_arg, dict);
820  else
821    pfunc(debugger_arg, PythonString(args),
822          ToSWIGWrapper(std::move(exe_ctx_ref_sp)), cmd_retobj_arg, dict);
823
824  return true;
825}
826
827bool lldb_private::LLDBSwigPythonCallCommandObject(
828    PyObject *implementor, lldb::DebuggerSP debugger, const char *args,
829    lldb_private::CommandReturnObject &cmd_retobj,
830    lldb::ExecutionContextRefSP exe_ctx_ref_sp) {
831  lldb::SBCommandReturnObject cmd_retobj_sb(cmd_retobj);
832
833  PyErr_Cleaner py_err_cleaner(true);
834
835  PythonObject self(PyRefType::Borrowed, implementor);
836  auto pfunc = self.ResolveName<PythonCallable>("__call__");
837
838  if (!pfunc.IsAllocated())
839    return false;
840
841  PythonObject cmd_retobj_arg(PyRefType::Owned,
842                              SBTypeToSWIGWrapper(cmd_retobj_sb));
843
844  pfunc(ToSWIGWrapper(std::move(debugger)), PythonString(args),
845        ToSWIGWrapper(exe_ctx_ref_sp), cmd_retobj_arg);
846
847  return true;
848}
849
850void *lldb_private::LLDBSWIGPythonCreateOSPlugin(
851    const char *python_class_name, const char *session_dictionary_name,
852    const lldb::ProcessSP &process_sp) {
853  if (python_class_name == NULL || python_class_name[0] == '\0' ||
854      !session_dictionary_name)
855    Py_RETURN_NONE;
856
857  PyErr_Cleaner py_err_cleaner(true);
858
859  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
860      session_dictionary_name);
861  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
862      python_class_name, dict);
863
864  if (!pfunc.IsAllocated())
865    Py_RETURN_NONE;
866
867  auto result = pfunc(ToSWIGWrapper(process_sp));
868
869  if (result.IsAllocated())
870    return result.release();
871
872  Py_RETURN_NONE;
873}
874
875void *lldb_private::LLDBSWIGPython_CreateFrameRecognizer(
876    const char *python_class_name, const char *session_dictionary_name) {
877  if (python_class_name == NULL || python_class_name[0] == '\0' ||
878      !session_dictionary_name)
879    Py_RETURN_NONE;
880
881  PyErr_Cleaner py_err_cleaner(true);
882
883  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
884      session_dictionary_name);
885  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
886      python_class_name, dict);
887
888  if (!pfunc.IsAllocated())
889    Py_RETURN_NONE;
890
891  auto result = pfunc();
892
893  if (result.IsAllocated())
894    return result.release();
895
896  Py_RETURN_NONE;
897}
898
899PyObject *lldb_private::LLDBSwigPython_GetRecognizedArguments(
900    PyObject * implementor, const lldb::StackFrameSP &frame_sp) {
901  static char callee_name[] = "get_recognized_arguments";
902
903  PythonObject arg = ToSWIGWrapper(frame_sp);
904
905  PythonString str(callee_name);
906  PyObject *result =
907      PyObject_CallMethodObjArgs(implementor, str.get(), arg.get(), NULL);
908  return result;
909}
910
911void *lldb_private::LLDBSWIGPython_GetDynamicSetting(
912    void *module, const char *setting, const lldb::TargetSP &target_sp) {
913  if (!module || !setting)
914    Py_RETURN_NONE;
915
916  PyErr_Cleaner py_err_cleaner(true);
917  PythonObject py_module(PyRefType::Borrowed, (PyObject *)module);
918  auto pfunc = py_module.ResolveName<PythonCallable>("get_dynamic_setting");
919
920  if (!pfunc.IsAllocated())
921    Py_RETURN_NONE;
922
923  auto result = pfunc(ToSWIGWrapper(target_sp), PythonString(setting));
924
925  return result.release();
926}
927
928bool lldb_private::LLDBSWIGPythonRunScriptKeywordProcess(
929    const char *python_function_name, const char *session_dictionary_name,
930    const lldb::ProcessSP &process, std::string &output) {
931
932  if (python_function_name == NULL || python_function_name[0] == '\0' ||
933      !session_dictionary_name)
934    return false;
935
936  PyErr_Cleaner py_err_cleaner(true);
937
938  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
939      session_dictionary_name);
940  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
941      python_function_name, dict);
942
943  if (!pfunc.IsAllocated())
944    return false;
945
946  auto result = pfunc(ToSWIGWrapper(process), dict);
947
948  output = result.Str().GetString().str();
949
950  return true;
951}
952
953llvm::Optional<std::string> lldb_private::LLDBSWIGPythonRunScriptKeywordThread(
954    const char *python_function_name, const char *session_dictionary_name,
955    lldb::ThreadSP thread) {
956  if (python_function_name == NULL || python_function_name[0] == '\0' ||
957      !session_dictionary_name)
958    return llvm::None;
959
960  PyErr_Cleaner py_err_cleaner(true);
961
962  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
963      session_dictionary_name);
964  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
965      python_function_name, dict);
966
967  if (!pfunc.IsAllocated())
968    return llvm::None;
969
970  auto result = pfunc(ToSWIGWrapper(std::move(thread)), dict);
971
972  return result.Str().GetString().str();
973}
974
975bool lldb_private::LLDBSWIGPythonRunScriptKeywordTarget(
976    const char *python_function_name, const char *session_dictionary_name,
977    const lldb::TargetSP &target, std::string &output) {
978
979  if (python_function_name == NULL || python_function_name[0] == '\0' ||
980      !session_dictionary_name)
981    return false;
982
983  PyErr_Cleaner py_err_cleaner(true);
984
985  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
986      session_dictionary_name);
987  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
988      python_function_name, dict);
989
990  if (!pfunc.IsAllocated())
991    return false;
992
993  auto result = pfunc(ToSWIGWrapper(target), dict);
994
995  output = result.Str().GetString().str();
996
997  return true;
998}
999
1000llvm::Optional<std::string> lldb_private::LLDBSWIGPythonRunScriptKeywordFrame(
1001    const char *python_function_name, const char *session_dictionary_name,
1002    lldb::StackFrameSP frame) {
1003  if (python_function_name == NULL || python_function_name[0] == '\0' ||
1004      !session_dictionary_name)
1005    return llvm::None;
1006
1007  PyErr_Cleaner py_err_cleaner(true);
1008
1009  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
1010      session_dictionary_name);
1011  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
1012      python_function_name, dict);
1013
1014  if (!pfunc.IsAllocated())
1015    return llvm::None;
1016
1017  auto result = pfunc(ToSWIGWrapper(std::move(frame)), dict);
1018
1019  return result.Str().GetString().str();
1020}
1021
1022bool lldb_private::LLDBSWIGPythonRunScriptKeywordValue(
1023    const char *python_function_name, const char *session_dictionary_name,
1024    const lldb::ValueObjectSP &value, std::string &output) {
1025
1026  if (python_function_name == NULL || python_function_name[0] == '\0' ||
1027      !session_dictionary_name)
1028    return false;
1029
1030  PyErr_Cleaner py_err_cleaner(true);
1031
1032  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
1033      session_dictionary_name);
1034  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
1035      python_function_name, dict);
1036
1037  if (!pfunc.IsAllocated())
1038    return false;
1039
1040  auto result = pfunc(ToSWIGWrapper(value), dict);
1041
1042  output = result.Str().GetString().str();
1043
1044  return true;
1045}
1046
1047bool lldb_private::LLDBSwigPythonCallModuleInit(
1048    const char *python_module_name, const char *session_dictionary_name,
1049    lldb::DebuggerSP debugger) {
1050  std::string python_function_name_string = python_module_name;
1051  python_function_name_string += ".__lldb_init_module";
1052  const char *python_function_name = python_function_name_string.c_str();
1053
1054  PyErr_Cleaner py_err_cleaner(true);
1055
1056  auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
1057      session_dictionary_name);
1058  auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
1059      python_function_name, dict);
1060
1061  // This method is optional and need not exist.  So if we don't find it,
1062  // it's actually a success, not a failure.
1063  if (!pfunc.IsAllocated())
1064    return true;
1065
1066  pfunc(ToSWIGWrapper(std::move(debugger)), dict);
1067
1068  return true;
1069}
1070
1071lldb::ValueObjectSP lldb_private::LLDBSWIGPython_GetValueObjectSPFromSBValue(
1072    void *data) {
1073  lldb::ValueObjectSP valobj_sp;
1074  if (data) {
1075    lldb::SBValue *sb_ptr = (lldb::SBValue *)data;
1076    valobj_sp = sb_ptr->GetSP();
1077  }
1078  return valobj_sp;
1079}
1080
1081// For the LogOutputCallback functions
1082static void LLDBSwigPythonCallPythonLogOutputCallback(const char *str,
1083                                                      void *baton) {
1084  if (baton != Py_None) {
1085    SWIG_PYTHON_THREAD_BEGIN_BLOCK;
1086    PyObject *result = PyObject_CallFunction(
1087        reinterpret_cast<PyObject *>(baton), const_cast<char *>("s"), str);
1088    Py_XDECREF(result);
1089    SWIG_PYTHON_THREAD_END_BLOCK;
1090  }
1091}
1092%}
1093