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    const 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    const 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(
294            PyRefType::Owned,
295            SBTypeToSWIGWrapper(*new lldb::SBStructuredData(args_impl)));
296        result = pfunc(target_arg, args_arg);
297    } else {
298        error_string.assign("wrong number of arguments in __init__, should be 2 (not including self)");
299        Py_RETURN_NONE;
300    }
301
302    if (result.IsAllocated())
303        return result.release();
304    Py_RETURN_NONE;
305}
306
307void*
308lldb_private::LLDBSwigPythonCreateScriptedThread
309(
310    const char *python_class_name,
311    const char *session_dictionary_name,
312    const lldb::ProcessSP& process_sp,
313    const StructuredDataImpl &args_impl,
314    std::string &error_string
315)
316{
317    if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
318        Py_RETURN_NONE;
319
320    PyErr_Cleaner py_err_cleaner(true);
321
322    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
323    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
324
325    if (!pfunc.IsAllocated()) {
326        error_string.append("could not find script class: ");
327        error_string.append(python_class_name);
328        return nullptr;
329    }
330
331    llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
332    if (!arg_info) {
333        llvm::handleAllErrors(
334            arg_info.takeError(),
335            [&](PythonException &E) {
336                error_string.append(E.ReadBacktrace());
337            },
338            [&](const llvm::ErrorInfoBase &E) {
339                error_string.append(E.message());
340            });
341        Py_RETURN_NONE;
342    }
343
344    PythonObject result = {};
345    if (arg_info.get().max_positional_args == 2) {
346        // FIXME: SBStructuredData leaked here
347        PythonObject args_arg(
348            PyRefType::Owned,
349            SBTypeToSWIGWrapper(*new lldb::SBStructuredData(args_impl)));
350        result = pfunc(ToSWIGWrapper(process_sp), args_arg);
351    } else {
352        error_string.assign("wrong number of arguments in __init__, should be 2 (not including self)");
353        Py_RETURN_NONE;
354    }
355
356    if (result.IsAllocated())
357        return result.release();
358    Py_RETURN_NONE;
359}
360
361void*
362lldb_private::LLDBSwigPythonCreateScriptedThreadPlan
363(
364    const char *python_class_name,
365    const char *session_dictionary_name,
366    const lldb_private::StructuredDataImpl &args_impl,
367    std::string &error_string,
368    const lldb::ThreadPlanSP& thread_plan_sp
369)
370{
371    if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
372        Py_RETURN_NONE;
373
374
375    PyErr_Cleaner py_err_cleaner(true);
376
377    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
378    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
379
380    if (!pfunc.IsAllocated()) {
381        error_string.append("could not find script class: ");
382        error_string.append(python_class_name);
383        return nullptr;
384    }
385
386    PythonObject tp_arg = ToSWIGWrapper(thread_plan_sp);
387
388    llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
389    if (!arg_info) {
390        llvm::handleAllErrors(
391            arg_info.takeError(),
392            [&](PythonException &E) {
393                error_string.append(E.ReadBacktrace());
394            },
395            [&](const llvm::ErrorInfoBase &E) {
396                error_string.append(E.message());
397            });
398        Py_RETURN_NONE;
399    }
400
401    PythonObject result = {};
402    // FIXME: SBStructuredData leaked here
403    auto *args_sb = new lldb::SBStructuredData(args_impl);
404    if (arg_info.get().max_positional_args == 2) {
405        if (args_sb->IsValid()) {
406           error_string.assign("args passed, but __init__ does not take an args dictionary");
407           Py_RETURN_NONE;
408        }
409        result = pfunc(tp_arg, dict);
410    } else if (arg_info.get().max_positional_args >= 3) {
411        PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*args_sb));
412        result = pfunc(tp_arg, args_arg, dict);
413    } else {
414        error_string.assign("wrong number of arguments in __init__, should be 2 or 3 (not including self)");
415        Py_RETURN_NONE;
416    }
417
418    // FIXME: At this point we should check that the class we found supports all the methods
419    // that we need.
420
421    if (result.IsAllocated())
422        return result.release();
423    Py_RETURN_NONE;
424}
425
426bool
427lldb_private::LLDBSWIGPythonCallThreadPlan
428(
429    void *implementor,
430    const char *method_name,
431    lldb_private::Event *event,
432    bool &got_error
433)
434{
435    got_error = false;
436
437    PyErr_Cleaner py_err_cleaner(false);
438    PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
439    auto pfunc = self.ResolveName<PythonCallable>(method_name);
440
441    if (!pfunc.IsAllocated())
442        return false;
443
444    PythonObject result;
445    if (event != nullptr)
446    {
447        lldb::SBEvent sb_event(event);
448        PythonObject event_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_event));
449        result = pfunc(event_arg);
450    }
451    else
452        result = pfunc();
453
454    if (PyErr_Occurred())
455    {
456        got_error = true;
457        printf ("Return value was neither false nor true for call to %s.\n", method_name);
458        PyErr_Print();
459        return false;
460    }
461
462    if (result.get() == Py_True)
463        return true;
464    else if (result.get() == Py_False)
465        return false;
466
467    // Somebody returned the wrong thing...
468    got_error = true;
469    printf ("Wrong return value type for call to %s.\n", method_name);
470    return false;
471}
472
473void *lldb_private::LLDBSwigPythonCreateScriptedBreakpointResolver(
474    const char *python_class_name, const char *session_dictionary_name,
475    const StructuredDataImpl &args_impl,
476    const lldb::BreakpointSP &breakpoint_sp) {
477
478    if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
479        Py_RETURN_NONE;
480
481    PyErr_Cleaner py_err_cleaner(true);
482
483    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
484    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
485
486    if (!pfunc.IsAllocated())
487        return nullptr;
488
489    // FIXME: SBStructuredData leaked here
490    lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl);
491    PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*args_value));
492
493    PythonObject result = pfunc(ToSWIGWrapper(breakpoint_sp), args_arg, dict);
494    // FIXME: At this point we should check that the class we found supports all the methods
495    // that we need.
496
497    if (result.IsAllocated())
498    {
499        // Check that __callback__ is defined:
500        auto callback_func = result.ResolveName<PythonCallable>("__callback__");
501        if (callback_func.IsAllocated())
502            return result.release();
503        else
504            result.release();
505    }
506    Py_RETURN_NONE;
507}
508
509unsigned int
510lldb_private::LLDBSwigPythonCallBreakpointResolver
511(
512    void *implementor,
513    const char *method_name,
514    lldb_private::SymbolContext *sym_ctx
515)
516{
517    PyErr_Cleaner py_err_cleaner(false);
518    PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
519    auto pfunc = self.ResolveName<PythonCallable>(method_name);
520
521    if (!pfunc.IsAllocated())
522        return 0;
523
524    PythonObject result;
525    if (sym_ctx != nullptr) {
526      lldb::SBSymbolContext sb_sym_ctx(sym_ctx);
527      PythonObject sym_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_sym_ctx));
528      result = pfunc(sym_ctx_arg);
529    } else
530      result = pfunc();
531
532    if (PyErr_Occurred())
533    {
534        PyErr_Print();
535        PyErr_Clear();
536        return 0;
537    }
538
539    // The callback will return a bool, but we're need to also return ints
540    // so we're squirrelling the bool through as an int...  And if you return
541    // nothing, we'll continue.
542    if (strcmp(method_name, "__callback__") == 0) {
543        if (result.get() == Py_False)
544          return 0;
545        else
546          return 1;
547    }
548
549    long long ret_val = unwrapOrSetPythonException(As<long long>(result));
550
551    if (PyErr_Occurred()) {
552        PyErr_Print();
553        PyErr_Clear();
554        return 0;
555    }
556
557    return ret_val;
558}
559
560void *
561lldb_private::LLDBSwigPythonCreateScriptedStopHook
562(
563    lldb::TargetSP target_sp,
564    const char *python_class_name,
565    const char *session_dictionary_name,
566    const StructuredDataImpl &args_impl,
567    Status &error
568)
569{
570    if (python_class_name == NULL || python_class_name[0] == '\0') {
571        error.SetErrorString("Empty class name.");
572        Py_RETURN_NONE;
573    }
574    if (!session_dictionary_name) {
575      error.SetErrorString("No session dictionary");
576      Py_RETURN_NONE;
577    }
578
579    PyErr_Cleaner py_err_cleaner(true);
580
581    auto dict =
582        PythonModule::MainModule().ResolveName<PythonDictionary>(
583            session_dictionary_name);
584    auto pfunc =
585        PythonObject::ResolveNameWithDictionary<PythonCallable>(
586            python_class_name, dict);
587
588    if (!pfunc.IsAllocated()) {
589        error.SetErrorStringWithFormat("Could not find class: %s.",
590                                       python_class_name);
591        return nullptr;
592    }
593
594    // FIXME: SBStructuredData leaked here
595    lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl);
596    PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*args_value));
597
598    PythonObject result = pfunc(ToSWIGWrapper(target_sp), args_arg, dict);
599
600    if (result.IsAllocated())
601    {
602        // Check that the handle_stop callback is defined:
603        auto callback_func = result.ResolveName<PythonCallable>("handle_stop");
604        if (callback_func.IsAllocated()) {
605          if (auto args_info = callback_func.GetArgInfo()) {
606            size_t num_args = (*args_info).max_positional_args;
607            if (num_args != 2) {
608              error.SetErrorStringWithFormat("Wrong number of args for "
609              "handle_stop callback, should be 2 (excluding self), got: %zu",
610              num_args);
611              Py_RETURN_NONE;
612            } else
613              return result.release();
614          } else {
615            error.SetErrorString("Couldn't get num arguments for handle_stop "
616                                 "callback.");
617            Py_RETURN_NONE;
618          }
619          return result.release();
620        }
621        else {
622          error.SetErrorStringWithFormat("Class \"%s\" is missing the required "
623                                         "handle_stop callback.",
624                                         python_class_name);
625          result.release();
626        }
627    }
628    Py_RETURN_NONE;
629}
630
631bool
632lldb_private::LLDBSwigPythonStopHookCallHandleStop
633(
634    void *implementor,
635    lldb::ExecutionContextRefSP exc_ctx_sp,
636    lldb::StreamSP stream
637)
638{
639    // handle_stop will return a bool with the meaning "should_stop"...
640    // If you return nothing we'll assume we are going to stop.
641    // Also any errors should return true, since we should stop on error.
642
643    PyErr_Cleaner py_err_cleaner(false);
644    PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
645    auto pfunc = self.ResolveName<PythonCallable>("handle_stop");
646
647    if (!pfunc.IsAllocated())
648        return true;
649
650    PythonObject result;
651    lldb::SBExecutionContext sb_exc_ctx(exc_ctx_sp);
652    PythonObject exc_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_exc_ctx));
653    lldb::SBStream sb_stream;
654    PythonObject sb_stream_arg(PyRefType::Owned,
655                               SBTypeToSWIGWrapper(sb_stream));
656    result = pfunc(exc_ctx_arg, sb_stream_arg);
657
658    if (PyErr_Occurred())
659    {
660        stream->PutCString("Python error occurred handling stop-hook.");
661        PyErr_Print();
662        PyErr_Clear();
663        return true;
664    }
665
666    // Now add the result to the output stream.  SBStream only
667    // makes an internally help StreamString which I can't interpose, so I
668    // have to copy it over here.
669    stream->PutCString(sb_stream.GetData());
670
671    if (result.get() == Py_False)
672      return false;
673    else
674      return true;
675}
676
677// wrapper that calls an optional instance member of an object taking no arguments
678static PyObject*
679LLDBSwigPython_CallOptionalMember
680(
681    PyObject* implementor,
682    char* callee_name,
683    PyObject* ret_if_not_found = Py_None,
684    bool* was_found = NULL
685)
686{
687    PyErr_Cleaner py_err_cleaner(false);
688
689    PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
690    auto pfunc = self.ResolveName<PythonCallable>(callee_name);
691
692    if (!pfunc.IsAllocated())
693    {
694        if (was_found)
695            *was_found = false;
696        Py_XINCREF(ret_if_not_found);
697        return ret_if_not_found;
698    }
699
700    if (was_found)
701        *was_found = true;
702
703    PythonObject result = pfunc();
704    return result.release();
705}
706
707size_t
708lldb_private::LLDBSwigPython_CalculateNumChildren
709(
710    PyObject *implementor,
711    uint32_t max
712)
713{
714    PythonObject self(PyRefType::Borrowed, implementor);
715    auto pfunc = self.ResolveName<PythonCallable>("num_children");
716
717    if (!pfunc.IsAllocated())
718        return 0;
719
720    auto arg_info = pfunc.GetArgInfo();
721    if (!arg_info) {
722        llvm::consumeError(arg_info.takeError());
723        return 0;
724    }
725
726    size_t ret_val;
727    if (arg_info.get().max_positional_args < 1)
728        ret_val = unwrapOrSetPythonException(As<long long>(pfunc.Call()));
729    else
730        ret_val = unwrapOrSetPythonException(As<long long>(pfunc.Call(PythonInteger(max))));
731
732    if (PyErr_Occurred())
733    {
734        PyErr_Print();
735        PyErr_Clear();
736        return 0;
737    }
738
739    if (arg_info.get().max_positional_args < 1)
740        ret_val = std::min(ret_val, static_cast<size_t>(max));
741
742    return ret_val;
743}
744
745PyObject*
746lldb_private::LLDBSwigPython_GetChildAtIndex
747(
748    PyObject *implementor,
749    uint32_t idx
750)
751{
752    PyErr_Cleaner py_err_cleaner(true);
753
754    PythonObject self(PyRefType::Borrowed, implementor);
755    auto pfunc = self.ResolveName<PythonCallable>("get_child_at_index");
756
757    if (!pfunc.IsAllocated())
758        return nullptr;
759
760    PythonObject result = pfunc(PythonInteger(idx));
761
762    if (!result.IsAllocated())
763        return nullptr;
764
765    lldb::SBValue* sbvalue_ptr = nullptr;
766    if (SWIG_ConvertPtr(result.get(), (void**)&sbvalue_ptr, SWIGTYPE_p_lldb__SBValue, 0) == -1)
767        return nullptr;
768
769    if (sbvalue_ptr == nullptr)
770        return nullptr;
771
772    return result.release();
773}
774
775int
776lldb_private::LLDBSwigPython_GetIndexOfChildWithName
777(
778    PyObject *implementor,
779    const char* child_name
780)
781{
782    PyErr_Cleaner py_err_cleaner(true);
783
784    PythonObject self(PyRefType::Borrowed, implementor);
785    auto pfunc = self.ResolveName<PythonCallable>("get_child_index");
786
787    if (!pfunc.IsAllocated())
788        return UINT32_MAX;
789
790    llvm::Expected<PythonObject> result = pfunc.Call(PythonString(child_name));
791
792    long long retval = unwrapOrSetPythonException(As<long long>(std::move(result)));
793
794    if (PyErr_Occurred()) {
795        PyErr_Clear(); // FIXME print this? do something else
796        return UINT32_MAX;
797    }
798
799    if (retval >= 0)
800        return (uint32_t)retval;
801
802    return UINT32_MAX;
803}
804
805bool
806lldb_private::LLDBSwigPython_UpdateSynthProviderInstance
807(
808    PyObject *implementor
809)
810{
811    bool ret_val = false;
812
813    static char callee_name[] = "update";
814
815    PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name);
816
817    if (py_return == Py_True)
818        ret_val = true;
819
820    Py_XDECREF(py_return);
821
822    return ret_val;
823}
824
825bool
826lldb_private::LLDBSwigPython_MightHaveChildrenSynthProviderInstance
827(
828    PyObject *implementor
829)
830{
831    bool ret_val = false;
832
833    static char callee_name[] = "has_children";
834
835    PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name, Py_True);
836
837    if (py_return == Py_True)
838        ret_val = true;
839
840    Py_XDECREF(py_return);
841
842    return ret_val;
843}
844
845PyObject*
846lldb_private::LLDBSwigPython_GetValueSynthProviderInstance
847(
848    PyObject *implementor
849)
850{
851    PyObject* ret_val = nullptr;
852
853    static char callee_name[] = "get_value";
854
855    PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name, Py_None);
856
857    if (py_return == Py_None || py_return == nullptr)
858        ret_val = nullptr;
859
860    lldb::SBValue* sbvalue_ptr = NULL;
861
862    if (SWIG_ConvertPtr(py_return, (void**)&sbvalue_ptr, SWIGTYPE_p_lldb__SBValue, 0) == -1)
863        ret_val = nullptr;
864    else if (sbvalue_ptr == NULL)
865        ret_val = nullptr;
866    else
867        ret_val = py_return;
868
869    Py_XDECREF(py_return);
870    return ret_val;
871}
872
873void*
874lldb_private::LLDBSWIGPython_CastPyObjectToSBData
875(
876    PyObject* data
877)
878{
879    lldb::SBData* sb_ptr = nullptr;
880
881    int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBData, 0);
882
883    if (valid_cast == -1)
884        return NULL;
885
886    return sb_ptr;
887}
888
889
890void*
891lldb_private::LLDBSWIGPython_CastPyObjectToSBError
892(
893    PyObject* data
894)
895{
896    lldb::SBError* sb_ptr = nullptr;
897
898    int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBError, 0);
899
900    if (valid_cast == -1)
901        return NULL;
902
903    return sb_ptr;
904}
905
906
907void*
908lldb_private::LLDBSWIGPython_CastPyObjectToSBValue
909(
910    PyObject* data
911)
912{
913    lldb::SBValue* sb_ptr = NULL;
914
915    int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBValue, 0);
916
917    if (valid_cast == -1)
918        return NULL;
919
920    return sb_ptr;
921}
922
923void*
924lldb_private::LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo
925(
926    PyObject* data
927)
928{
929    lldb::SBMemoryRegionInfo* sb_ptr = NULL;
930
931    int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBMemoryRegionInfo, 0);
932
933    if (valid_cast == -1)
934        return NULL;
935
936    return sb_ptr;
937}
938
939bool
940lldb_private::LLDBSwigPythonCallCommand
941(
942    const char *python_function_name,
943    const char *session_dictionary_name,
944    lldb::DebuggerSP& debugger,
945    const char* args,
946    lldb_private::CommandReturnObject& cmd_retobj,
947    lldb::ExecutionContextRefSP exe_ctx_ref_sp
948)
949{
950    lldb::SBCommandReturnObject cmd_retobj_sb(cmd_retobj);
951    lldb::SBDebugger debugger_sb(debugger);
952    lldb::SBExecutionContext exe_ctx_sb(exe_ctx_ref_sp);
953
954    PyErr_Cleaner py_err_cleaner(true);
955    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
956    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
957
958    if (!pfunc.IsAllocated())
959        return false;
960
961    auto argc = pfunc.GetArgInfo();
962    if (!argc) {
963        llvm::consumeError(argc.takeError());
964        return false;
965    }
966    PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb));
967    PythonObject exe_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(exe_ctx_sb));
968    PythonObject cmd_retobj_arg(PyRefType::Owned, SBTypeToSWIGWrapper(cmd_retobj_sb));
969
970    if (argc.get().max_positional_args < 5u)
971        pfunc(debugger_arg, PythonString(args), cmd_retobj_arg, dict);
972    else
973        pfunc(debugger_arg, PythonString(args), exe_ctx_arg, cmd_retobj_arg, dict);
974
975    return true;
976}
977
978bool
979lldb_private::LLDBSwigPythonCallCommandObject
980(
981    PyObject *implementor,
982    lldb::DebuggerSP& debugger,
983    const char* args,
984    lldb_private::CommandReturnObject& cmd_retobj,
985    lldb::ExecutionContextRefSP exe_ctx_ref_sp
986)
987{
988    lldb::SBCommandReturnObject cmd_retobj_sb(cmd_retobj);
989    lldb::SBDebugger debugger_sb(debugger);
990    lldb::SBExecutionContext exe_ctx_sb(exe_ctx_ref_sp);
991
992    PyErr_Cleaner py_err_cleaner(true);
993
994    PythonObject self(PyRefType::Borrowed, implementor);
995    auto pfunc = self.ResolveName<PythonCallable>("__call__");
996
997    if (!pfunc.IsAllocated())
998        return false;
999
1000    PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb));
1001    PythonObject exe_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(exe_ctx_sb));
1002    PythonObject cmd_retobj_arg(PyRefType::Owned, SBTypeToSWIGWrapper(cmd_retobj_sb));
1003
1004    pfunc(debugger_arg, PythonString(args), exe_ctx_arg, cmd_retobj_arg);
1005
1006    return true;
1007}
1008
1009void*
1010lldb_private::LLDBSWIGPythonCreateOSPlugin
1011(
1012    const char *python_class_name,
1013    const char *session_dictionary_name,
1014    const lldb::ProcessSP& process_sp
1015)
1016{
1017    if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
1018        Py_RETURN_NONE;
1019
1020    PyErr_Cleaner py_err_cleaner(true);
1021
1022    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
1023    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
1024
1025    if (!pfunc.IsAllocated())
1026        Py_RETURN_NONE;
1027
1028    auto result = pfunc(ToSWIGWrapper(process_sp));
1029
1030    if (result.IsAllocated())
1031        return result.release();
1032
1033    Py_RETURN_NONE;
1034}
1035
1036void*
1037lldb_private::LLDBSWIGPython_CreateFrameRecognizer
1038(
1039    const char *python_class_name,
1040    const char *session_dictionary_name
1041)
1042{
1043    if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
1044        Py_RETURN_NONE;
1045
1046    PyErr_Cleaner py_err_cleaner(true);
1047
1048    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
1049    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
1050
1051    if (!pfunc.IsAllocated())
1052        Py_RETURN_NONE;
1053
1054    auto result = pfunc();
1055
1056    if (result.IsAllocated())
1057        return result.release();
1058
1059    Py_RETURN_NONE;
1060}
1061
1062PyObject*
1063lldb_private::LLDBSwigPython_GetRecognizedArguments
1064(
1065    PyObject *implementor,
1066    const lldb::StackFrameSP& frame_sp
1067)
1068{
1069    static char callee_name[] = "get_recognized_arguments";
1070
1071    lldb::SBFrame frame_sb(frame_sp);
1072    PyObject *arg = SBTypeToSWIGWrapper(frame_sb);
1073
1074    PythonString str(callee_name);
1075    PyObject* result = PyObject_CallMethodObjArgs(implementor, str.get(), arg,
1076                                                  NULL);
1077    return result;
1078}
1079
1080void*
1081lldb_private::LLDBSWIGPython_GetDynamicSetting (void* module, const char* setting, const lldb::TargetSP& target_sp)
1082{
1083    if (!module || !setting)
1084        Py_RETURN_NONE;
1085
1086    PyErr_Cleaner py_err_cleaner(true);
1087    PythonObject py_module(PyRefType::Borrowed, (PyObject *)module);
1088    auto pfunc = py_module.ResolveName<PythonCallable>("get_dynamic_setting");
1089
1090    if (!pfunc.IsAllocated())
1091        Py_RETURN_NONE;
1092
1093    auto result = pfunc(ToSWIGWrapper(target_sp), PythonString(setting));
1094
1095    return result.release();
1096}
1097
1098bool lldb_private::LLDBSWIGPythonRunScriptKeywordProcess(
1099    const char *python_function_name, const char *session_dictionary_name,
1100    const lldb::ProcessSP &process, std::string &output) {
1101
1102    if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
1103        return false;
1104
1105    PyErr_Cleaner py_err_cleaner(true);
1106
1107    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
1108    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
1109
1110    if (!pfunc.IsAllocated())
1111        return false;
1112
1113    auto result = pfunc(ToSWIGWrapper(process), dict);
1114
1115    output = result.Str().GetString().str();
1116
1117    return true;
1118}
1119
1120bool
1121lldb_private::LLDBSWIGPythonRunScriptKeywordThread
1122(const char* python_function_name,
1123const char* session_dictionary_name,
1124lldb::ThreadSP& thread,
1125std::string& output)
1126
1127{
1128    if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
1129        return false;
1130
1131    PyErr_Cleaner py_err_cleaner(true);
1132
1133    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
1134    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
1135
1136    if (!pfunc.IsAllocated())
1137        return false;
1138
1139    lldb::SBThread thread_sb(thread);
1140    PythonObject thread_arg(PyRefType::Owned, SBTypeToSWIGWrapper(thread_sb));
1141    auto result = pfunc(thread_arg, dict);
1142
1143    output = result.Str().GetString().str();
1144
1145    return true;
1146}
1147
1148bool lldb_private::LLDBSWIGPythonRunScriptKeywordTarget(
1149    const char *python_function_name, const char *session_dictionary_name,
1150    const lldb::TargetSP &target, std::string &output) {
1151
1152    if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
1153        return false;
1154
1155    PyErr_Cleaner py_err_cleaner(true);
1156
1157    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
1158    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name,dict);
1159
1160    if (!pfunc.IsAllocated())
1161        return false;
1162
1163    auto result = pfunc(ToSWIGWrapper(target), dict);
1164
1165    output = result.Str().GetString().str();
1166
1167    return true;
1168}
1169
1170bool
1171lldb_private::LLDBSWIGPythonRunScriptKeywordFrame
1172(const char* python_function_name,
1173const char* session_dictionary_name,
1174lldb::StackFrameSP& frame,
1175std::string& output)
1176
1177{
1178    if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
1179        return false;
1180
1181    PyErr_Cleaner py_err_cleaner(true);
1182
1183    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
1184    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name,dict);
1185
1186    if (!pfunc.IsAllocated())
1187        return false;
1188
1189    lldb::SBFrame frame_sb(frame);
1190    PythonObject frame_arg(PyRefType::Owned, SBTypeToSWIGWrapper(frame_sb));
1191    auto result = pfunc(frame_arg, dict);
1192
1193    output = result.Str().GetString().str();
1194
1195    return true;
1196}
1197
1198bool lldb_private::LLDBSWIGPythonRunScriptKeywordValue(
1199    const char *python_function_name, const char *session_dictionary_name,
1200    const lldb::ValueObjectSP &value, std::string &output) {
1201
1202    if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
1203        return false;
1204
1205    PyErr_Cleaner py_err_cleaner(true);
1206
1207    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
1208    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
1209
1210    if (!pfunc.IsAllocated())
1211        return false;
1212
1213    auto result = pfunc(ToSWIGWrapper(value), dict);
1214
1215    output = result.Str().GetString().str();
1216
1217    return true;
1218}
1219
1220bool
1221lldb_private::LLDBSwigPythonCallModuleInit
1222(
1223    const char *python_module_name,
1224    const char *session_dictionary_name,
1225    lldb::DebuggerSP& debugger
1226)
1227{
1228    std::string python_function_name_string = python_module_name;
1229    python_function_name_string += ".__lldb_init_module";
1230    const char* python_function_name = python_function_name_string.c_str();
1231
1232    PyErr_Cleaner py_err_cleaner(true);
1233
1234    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
1235    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
1236
1237    // This method is optional and need not exist.  So if we don't find it,
1238    // it's actually a success, not a failure.
1239    if (!pfunc.IsAllocated())
1240        return true;
1241
1242    lldb::SBDebugger debugger_sb(debugger);
1243    PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb));
1244    pfunc(debugger_arg, dict);
1245
1246    return true;
1247}
1248
1249lldb::ValueObjectSP
1250lldb_private::LLDBSWIGPython_GetValueObjectSPFromSBValue (void* data)
1251{
1252    lldb::ValueObjectSP valobj_sp;
1253    if (data)
1254    {
1255        lldb::SBValue* sb_ptr = (lldb::SBValue *)data;
1256        valobj_sp = sb_ptr->GetSP();
1257    }
1258    return valobj_sp;
1259}
1260
1261// For the LogOutputCallback functions
1262static void LLDBSwigPythonCallPythonLogOutputCallback(const char *str, void *baton) {
1263    if (baton != Py_None) {
1264      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
1265      PyObject *result = PyObject_CallFunction(reinterpret_cast<PyObject*>(baton), const_cast<char*>("s"), str);
1266	  Py_XDECREF(result);
1267      SWIG_PYTHON_THREAD_END_BLOCK;
1268    }
1269}
1270%}
1271