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