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