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