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