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