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