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