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