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