xref: /freebsd/contrib/llvm-project/lldb/bindings/python/python-wrapper.swig (revision 130d950cafcd29c6a32cf5357bf600dcd9c1d998)
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    // I do not want the SBThreadPlan to be deallocated when going out of scope because python
275    // has ownership of it and will manage memory for this object by itself
276    lldb::SBThreadPlan *tp_value = new lldb::SBThreadPlan(thread_plan_sp);
277
278    PyErr_Cleaner py_err_cleaner(true);
279
280    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
281    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
282
283    if (!pfunc.IsAllocated()) {
284        error_string.append("could not find script class: ");
285        error_string.append(python_class_name);
286        return nullptr;
287    }
288
289    PythonObject tp_arg(PyRefType::Owned, SBTypeToSWIGWrapper(tp_value));
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        lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl);
316        PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(args_value));
317        result = pfunc(tp_arg, args_arg, dict);
318    } else {
319        error_string.assign("wrong number of arguments in __init__, should be 2 or 3 (not including self)");
320        Py_RETURN_NONE;
321    }
322
323    // FIXME: At this point we should check that the class we found supports all the methods
324    // that we need.
325
326    if (result.IsAllocated())
327        return result.release();
328    Py_RETURN_NONE;
329}
330
331SWIGEXPORT bool
332LLDBSWIGPythonCallThreadPlan
333(
334    void *implementor,
335    const char *method_name,
336    lldb_private::Event *event,
337    bool &got_error
338)
339{
340    got_error = false;
341
342    PyErr_Cleaner py_err_cleaner(false);
343    PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
344    auto pfunc = self.ResolveName<PythonCallable>(method_name);
345
346    if (!pfunc.IsAllocated())
347        return false;
348
349    PythonObject result;
350    if (event != nullptr)
351    {
352        lldb::SBEvent sb_event(event);
353        PythonObject event_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_event));
354        result = pfunc(event_arg);
355    }
356    else
357        result = pfunc();
358
359    if (PyErr_Occurred())
360    {
361        got_error = true;
362        printf ("Return value was neither false nor true for call to %s.\n", method_name);
363        PyErr_Print();
364        return false;
365    }
366
367    if (result.get() == Py_True)
368        return true;
369    else if (result.get() == Py_False)
370        return false;
371
372    // Somebody returned the wrong thing...
373    got_error = true;
374    printf ("Wrong return value type for call to %s.\n", method_name);
375    return false;
376}
377
378SWIGEXPORT void *
379LLDBSwigPythonCreateScriptedBreakpointResolver
380(
381    const char *python_class_name,
382    const char *session_dictionary_name,
383    lldb_private::StructuredDataImpl *args_impl,
384    lldb::BreakpointSP &breakpoint_sp
385)
386{
387    if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
388        Py_RETURN_NONE;
389
390    PyErr_Cleaner py_err_cleaner(true);
391
392    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
393    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
394
395    if (!pfunc.IsAllocated())
396        return nullptr;
397
398    lldb::SBBreakpoint *bkpt_value = new lldb::SBBreakpoint(breakpoint_sp);
399
400    PythonObject bkpt_arg(PyRefType::Owned, SBTypeToSWIGWrapper(bkpt_value));
401
402    lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl);
403    PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(args_value));
404
405    PythonObject result = pfunc(bkpt_arg, args_arg, dict);
406    // FIXME: At this point we should check that the class we found supports all the methods
407    // that we need.
408
409    if (result.IsAllocated())
410    {
411        // Check that __callback__ is defined:
412        auto callback_func = result.ResolveName<PythonCallable>("__callback__");
413        if (callback_func.IsAllocated())
414            return result.release();
415        else
416            result.release();
417    }
418    Py_RETURN_NONE;
419}
420
421SWIGEXPORT unsigned int
422LLDBSwigPythonCallBreakpointResolver
423(
424    void *implementor,
425    const char *method_name,
426    lldb_private::SymbolContext *sym_ctx
427)
428{
429    PyErr_Cleaner py_err_cleaner(false);
430    PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
431    auto pfunc = self.ResolveName<PythonCallable>(method_name);
432
433    if (!pfunc.IsAllocated())
434        return 0;
435
436    PythonObject result;
437    if (sym_ctx != nullptr) {
438      lldb::SBSymbolContext sb_sym_ctx(sym_ctx);
439      PythonObject sym_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_sym_ctx));
440      result = pfunc(sym_ctx_arg);
441    } else
442      result = pfunc();
443
444    if (PyErr_Occurred())
445    {
446        PyErr_Print();
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    PythonInteger int_result = result.AsType<PythonInteger>();
461    if (!int_result.IsAllocated())
462        return 0;
463
464    unsigned int ret_val = int_result.GetInteger();
465
466    return ret_val;
467}
468
469// wrapper that calls an optional instance member of an object taking no arguments
470static PyObject*
471LLDBSwigPython_CallOptionalMember
472(
473    PyObject* implementor,
474    char* callee_name,
475    PyObject* ret_if_not_found = Py_None,
476    bool* was_found = NULL
477)
478{
479    PyErr_Cleaner py_err_cleaner(false);
480
481    PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
482    auto pfunc = self.ResolveName<PythonCallable>(callee_name);
483
484    if (!pfunc.IsAllocated())
485    {
486        if (was_found)
487            *was_found = false;
488        Py_XINCREF(ret_if_not_found);
489        return ret_if_not_found;
490    }
491
492    if (was_found)
493        *was_found = true;
494
495    PythonObject result = pfunc();
496    return result.release();
497}
498
499SWIGEXPORT size_t
500LLDBSwigPython_CalculateNumChildren
501(
502    PyObject *implementor,
503    uint32_t max
504)
505{
506    PythonObject self(PyRefType::Borrowed, implementor);
507    auto pfunc = self.ResolveName<PythonCallable>("num_children");
508
509    if (!pfunc.IsAllocated())
510        return 0;
511
512    auto arg_info = pfunc.GetArgInfo();
513    if (!arg_info) {
514        llvm::consumeError(arg_info.takeError());
515        return 0;
516    }
517
518    PythonObject result;
519
520    if (arg_info.get().max_positional_args < 1)
521        result = pfunc();
522    else
523        result = pfunc(PythonInteger(max));
524
525    if (!result.IsAllocated())
526        return 0;
527
528    PythonInteger int_result = result.AsType<PythonInteger>();
529    if (!int_result.IsAllocated())
530        return 0;
531
532    size_t ret_val = int_result.GetInteger();
533
534    if (PyErr_Occurred()) //FIXME use Expected to catch python exceptions
535    {
536        PyErr_Print();
537        PyErr_Clear();
538    }
539
540    if (arg_info.get().max_positional_args < 1)
541        ret_val = std::min(ret_val, static_cast<size_t>(max));
542
543    return ret_val;
544}
545
546SWIGEXPORT PyObject*
547LLDBSwigPython_GetChildAtIndex
548(
549    PyObject *implementor,
550    uint32_t idx
551)
552{
553    PyErr_Cleaner py_err_cleaner(true);
554
555    PythonObject self(PyRefType::Borrowed, implementor);
556    auto pfunc = self.ResolveName<PythonCallable>("get_child_at_index");
557
558    if (!pfunc.IsAllocated())
559        return nullptr;
560
561    PythonObject result = pfunc(PythonInteger(idx));
562
563    if (!result.IsAllocated())
564        return nullptr;
565
566    lldb::SBValue* sbvalue_ptr = nullptr;
567    if (SWIG_ConvertPtr(result.get(), (void**)&sbvalue_ptr, SWIGTYPE_p_lldb__SBValue, 0) == -1)
568        return nullptr;
569
570    if (sbvalue_ptr == nullptr)
571        return nullptr;
572
573    return result.release();
574}
575
576SWIGEXPORT int
577LLDBSwigPython_GetIndexOfChildWithName
578(
579    PyObject *implementor,
580    const char* child_name
581)
582{
583    PyErr_Cleaner py_err_cleaner(true);
584
585    PythonObject self(PyRefType::Borrowed, implementor);
586    auto pfunc = self.ResolveName<PythonCallable>("get_child_index");
587
588    if (!pfunc.IsAllocated())
589        return UINT32_MAX;
590
591    PythonObject result = pfunc(PythonString(child_name));
592
593    if (!result.IsAllocated())
594        return UINT32_MAX;
595
596    PythonInteger int_result = result.AsType<PythonInteger>();
597    if (!int_result.IsAllocated())
598        return UINT32_MAX;
599
600    int64_t retval = int_result.GetInteger();
601    if (retval >= 0)
602        return (uint32_t)retval;
603
604    return UINT32_MAX;
605}
606
607SWIGEXPORT bool
608LLDBSwigPython_UpdateSynthProviderInstance
609(
610    PyObject *implementor
611)
612{
613    bool ret_val = false;
614
615    static char callee_name[] = "update";
616
617    PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name);
618
619    if (py_return == Py_True)
620        ret_val = true;
621
622    Py_XDECREF(py_return);
623
624    return ret_val;
625}
626
627SWIGEXPORT bool
628LLDBSwigPython_MightHaveChildrenSynthProviderInstance
629(
630    PyObject *implementor
631)
632{
633    bool ret_val = false;
634
635    static char callee_name[] = "has_children";
636
637    PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name, Py_True);
638
639    if (py_return == Py_True)
640        ret_val = true;
641
642    Py_XDECREF(py_return);
643
644    return ret_val;
645}
646
647SWIGEXPORT PyObject*
648LLDBSwigPython_GetValueSynthProviderInstance
649(
650    PyObject *implementor
651)
652{
653    PyObject* ret_val = nullptr;
654
655    static char callee_name[] = "get_value";
656
657    PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name, Py_None);
658
659    if (py_return == Py_None || py_return == nullptr)
660        ret_val = nullptr;
661
662    lldb::SBValue* sbvalue_ptr = NULL;
663
664    if (SWIG_ConvertPtr(py_return, (void**)&sbvalue_ptr, SWIGTYPE_p_lldb__SBValue, 0) == -1)
665        ret_val = nullptr;
666    else if (sbvalue_ptr == NULL)
667        ret_val = nullptr;
668    else
669        ret_val = py_return;
670
671    Py_XDECREF(py_return);
672    return ret_val;
673}
674
675SWIGEXPORT void*
676LLDBSWIGPython_CastPyObjectToSBValue
677(
678    PyObject* data
679)
680{
681    lldb::SBValue* sb_ptr = NULL;
682
683    int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBValue, 0);
684
685    if (valid_cast == -1)
686        return NULL;
687
688    return sb_ptr;
689}
690
691SWIGEXPORT bool
692LLDBSwigPythonCallCommand
693(
694    const char *python_function_name,
695    const char *session_dictionary_name,
696    lldb::DebuggerSP& debugger,
697    const char* args,
698    lldb_private::CommandReturnObject& cmd_retobj,
699    lldb::ExecutionContextRefSP exe_ctx_ref_sp
700)
701{
702    lldb::SBCommandReturnObject cmd_retobj_sb(cmd_retobj);
703    lldb::SBDebugger debugger_sb(debugger);
704    lldb::SBExecutionContext exe_ctx_sb(exe_ctx_ref_sp);
705
706    PyErr_Cleaner py_err_cleaner(true);
707    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
708    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
709
710    if (!pfunc.IsAllocated())
711        return false;
712
713    // pass the pointer-to cmd_retobj_sb or watch the underlying object disappear from under you
714    // see comment above for SBCommandReturnObjectReleaser for further details
715    auto argc = pfunc.GetArgInfo();
716    if (!argc) {
717        llvm::consumeError(argc.takeError());
718        return false;
719    }
720    PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb));
721    PythonObject exe_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(exe_ctx_sb));
722    PythonObject cmd_retobj_arg(PyRefType::Owned, SBTypeToSWIGWrapper(&cmd_retobj_sb));
723
724    if (argc.get().max_positional_args < 5u)
725        pfunc(debugger_arg, PythonString(args), cmd_retobj_arg, dict);
726    else
727        pfunc(debugger_arg, PythonString(args), exe_ctx_arg, cmd_retobj_arg, dict);
728
729    return true;
730}
731
732SWIGEXPORT bool
733LLDBSwigPythonCallCommandObject
734(
735    PyObject *implementor,
736    lldb::DebuggerSP& debugger,
737    const char* args,
738    lldb_private::CommandReturnObject& cmd_retobj,
739    lldb::ExecutionContextRefSP exe_ctx_ref_sp
740)
741{
742    lldb::SBCommandReturnObject cmd_retobj_sb(cmd_retobj);
743    lldb::SBDebugger debugger_sb(debugger);
744    lldb::SBExecutionContext exe_ctx_sb(exe_ctx_ref_sp);
745
746    PyErr_Cleaner py_err_cleaner(true);
747
748    PythonObject self(PyRefType::Borrowed, implementor);
749    auto pfunc = self.ResolveName<PythonCallable>("__call__");
750
751    if (!pfunc.IsAllocated())
752        return false;
753
754    // pass the pointer-to cmd_retobj_sb or watch the underlying object disappear from under you
755    // see comment above for SBCommandReturnObjectReleaser for further details
756    PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb));
757    PythonObject exe_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(exe_ctx_sb));
758    PythonObject cmd_retobj_arg(PyRefType::Owned, SBTypeToSWIGWrapper(&cmd_retobj_sb));
759
760    pfunc(debugger_arg, PythonString(args), exe_ctx_arg, cmd_retobj_arg);
761
762    return true;
763}
764
765SWIGEXPORT void*
766LLDBSWIGPythonCreateOSPlugin
767(
768    const char *python_class_name,
769    const char *session_dictionary_name,
770    const lldb::ProcessSP& process_sp
771)
772{
773    if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
774        Py_RETURN_NONE;
775
776    PyErr_Cleaner py_err_cleaner(true);
777
778    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
779    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
780
781    if (!pfunc.IsAllocated())
782        Py_RETURN_NONE;
783
784    // I do not want the SBProcess to be deallocated when going out of scope because python
785    // has ownership of it and will manage memory for this object by itself
786    lldb::SBProcess *process_sb = new lldb::SBProcess(process_sp);
787    PythonObject process_arg(PyRefType::Owned, SBTypeToSWIGWrapper(process_sb));
788    if (!process_arg.IsAllocated())
789        Py_RETURN_NONE;
790
791    auto result = pfunc(process_arg);
792
793    if (result.IsAllocated())
794        return result.release();
795
796    Py_RETURN_NONE;
797}
798
799SWIGEXPORT void*
800LLDBSWIGPython_CreateFrameRecognizer
801(
802    const char *python_class_name,
803    const char *session_dictionary_name
804)
805{
806    if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
807        Py_RETURN_NONE;
808
809    PyErr_Cleaner py_err_cleaner(true);
810
811    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
812    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
813
814    if (!pfunc.IsAllocated())
815        Py_RETURN_NONE;
816
817    auto result = pfunc();
818
819    if (result.IsAllocated())
820        return result.release();
821
822    Py_RETURN_NONE;
823}
824
825SWIGEXPORT PyObject*
826LLDBSwigPython_GetRecognizedArguments
827(
828    PyObject *implementor,
829    const lldb::StackFrameSP& frame_sp
830)
831{
832    static char callee_name[] = "get_recognized_arguments";
833
834    lldb::SBFrame frame_sb(frame_sp);
835    PyObject *arg = SBTypeToSWIGWrapper(frame_sb);
836
837    PythonString str(callee_name);
838    PyObject* result = PyObject_CallMethodObjArgs(implementor, str.get(), arg,
839                                                  NULL);
840    return result;
841}
842
843SWIGEXPORT void*
844LLDBSWIGPython_GetDynamicSetting (void* module, const char* setting, const lldb::TargetSP& target_sp)
845{
846    if (!module || !setting)
847        Py_RETURN_NONE;
848
849    PyErr_Cleaner py_err_cleaner(true);
850    PythonObject py_module(PyRefType::Borrowed, (PyObject *)module);
851    auto pfunc = py_module.ResolveName<PythonCallable>("get_dynamic_setting");
852
853    if (!pfunc.IsAllocated())
854        Py_RETURN_NONE;
855
856    lldb::SBTarget target_sb(target_sp);
857    PythonObject target_arg(PyRefType::Owned, SBTypeToSWIGWrapper(target_sb));
858    auto result = pfunc(target_arg, PythonString(setting));
859
860    return result.release();
861}
862
863SWIGEXPORT bool
864LLDBSWIGPythonRunScriptKeywordProcess
865(const char* python_function_name,
866const char* session_dictionary_name,
867lldb::ProcessSP& process,
868std::string& output)
869
870{
871    if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
872        return false;
873
874    PyErr_Cleaner py_err_cleaner(true);
875
876    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
877    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
878
879    if (!pfunc.IsAllocated())
880        return false;
881
882    lldb::SBProcess process_sb(process);
883    PythonObject process_arg(PyRefType::Owned, SBTypeToSWIGWrapper(process_sb));
884    auto result = pfunc(process_arg, dict);
885
886    output = result.Str().GetString().str();
887
888    return true;
889}
890
891SWIGEXPORT bool
892LLDBSWIGPythonRunScriptKeywordThread
893(const char* python_function_name,
894const char* session_dictionary_name,
895lldb::ThreadSP& thread,
896std::string& output)
897
898{
899    if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
900        return false;
901
902    PyErr_Cleaner py_err_cleaner(true);
903
904    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
905    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
906
907    if (!pfunc.IsAllocated())
908        return false;
909
910    lldb::SBThread thread_sb(thread);
911    PythonObject thread_arg(PyRefType::Owned, SBTypeToSWIGWrapper(thread_sb));
912    auto result = pfunc(thread_arg, dict);
913
914    output = result.Str().GetString().str();
915
916    return true;
917}
918
919SWIGEXPORT bool
920LLDBSWIGPythonRunScriptKeywordTarget
921(const char* python_function_name,
922const char* session_dictionary_name,
923lldb::TargetSP& target,
924std::string& output)
925
926{
927    if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
928        return false;
929
930    PyErr_Cleaner py_err_cleaner(true);
931
932    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
933    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name,dict);
934
935    if (!pfunc.IsAllocated())
936        return false;
937
938    lldb::SBTarget target_sb(target);
939    PythonObject target_arg(PyRefType::Owned, SBTypeToSWIGWrapper(target_sb));
940    auto result = pfunc(target_arg, dict);
941
942    output = result.Str().GetString().str();
943
944    return true;
945}
946
947SWIGEXPORT bool
948LLDBSWIGPythonRunScriptKeywordFrame
949(const char* python_function_name,
950const char* session_dictionary_name,
951lldb::StackFrameSP& frame,
952std::string& output)
953
954{
955    if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
956        return false;
957
958    PyErr_Cleaner py_err_cleaner(true);
959
960    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
961    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name,dict);
962
963    if (!pfunc.IsAllocated())
964        return false;
965
966    lldb::SBFrame frame_sb(frame);
967    PythonObject frame_arg(PyRefType::Owned, SBTypeToSWIGWrapper(frame_sb));
968    auto result = pfunc(frame_arg, dict);
969
970    output = result.Str().GetString().str();
971
972    return true;
973}
974
975SWIGEXPORT bool
976LLDBSWIGPythonRunScriptKeywordValue
977(const char* python_function_name,
978const char* session_dictionary_name,
979lldb::ValueObjectSP& value,
980std::string& output)
981
982{
983    if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
984        return false;
985
986    PyErr_Cleaner py_err_cleaner(true);
987
988    auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
989    auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
990
991    if (!pfunc.IsAllocated())
992        return false;
993
994    lldb::SBValue value_sb(value);
995    PythonObject value_arg(PyRefType::Owned, SBTypeToSWIGWrapper(value_sb));
996    auto result = pfunc(value_arg, dict);
997
998    output = result.Str().GetString().str();
999
1000    return true;
1001}
1002
1003SWIGEXPORT bool
1004LLDBSwigPythonCallModuleInit
1005(
1006    const char *python_module_name,
1007    const char *session_dictionary_name,
1008    lldb::DebuggerSP& debugger
1009)
1010{
1011    std::string python_function_name_string = python_module_name;
1012    python_function_name_string += ".__lldb_init_module";
1013    const char* python_function_name = python_function_name_string.c_str();
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    // This method is optional and need not exist.  So if we don't find it,
1021    // it's actually a success, not a failure.
1022    if (!pfunc.IsAllocated())
1023        return true;
1024
1025    lldb::SBDebugger debugger_sb(debugger);
1026    PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb));
1027    pfunc(debugger_arg, dict);
1028
1029    return true;
1030}
1031%}
1032
1033
1034%runtime %{
1035// Forward declaration to be inserted at the start of LLDBWrapPython.h
1036#include "lldb/API/SBDebugger.h"
1037#include "lldb/API/SBValue.h"
1038
1039SWIGEXPORT lldb::ValueObjectSP
1040LLDBSWIGPython_GetValueObjectSPFromSBValue (void* data)
1041{
1042    lldb::ValueObjectSP valobj_sp;
1043    if (data)
1044    {
1045        lldb::SBValue* sb_ptr = (lldb::SBValue *)data;
1046        valobj_sp = sb_ptr->GetSP();
1047    }
1048    return valobj_sp;
1049}
1050
1051#ifdef __cplusplus
1052extern "C" {
1053#endif
1054
1055void LLDBSwigPythonCallPythonLogOutputCallback(const char *str, void *baton);
1056
1057#ifdef __cplusplus
1058}
1059#endif
1060%}
1061
1062%wrapper %{
1063
1064
1065// For the LogOutputCallback functions
1066void LLDBSwigPythonCallPythonLogOutputCallback(const char *str, void *baton) {
1067    if (baton != Py_None) {
1068      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
1069      PyObject *result = PyObject_CallFunction(reinterpret_cast<PyObject*>(baton), const_cast<char*>("s"), str);
1070	  Py_XDECREF(result);
1071      SWIG_PYTHON_THREAD_END_BLOCK;
1072    }
1073}
1074%}
1075