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