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