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