diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h --- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -315,8 +315,7 @@ Status SetBreakpointCommandCallbackFunction( std::vector &bp_options_vec, - const char *function_name, - StructuredData::ObjectSP extra_args_sp); + const char *function_name, StructuredData::ObjectSP extra_args_sp); /// Set a script function as the callback for the breakpoint. virtual Status @@ -472,9 +471,9 @@ const char *GetScriptInterpreterPtyName(); int GetMasterFileDescriptor(); - - virtual llvm::Expected - GetNumFixedArgumentsForCallable(const llvm::StringRef &callable_name) { + + virtual llvm::Expected + GetMaxPositionalArgumentsForCallable(const llvm::StringRef &callable_name) { return llvm::createStringError( llvm::inconvertibleErrorCode(), "Unimplemented function"); } diff --git a/lldb/scripts/Python/python-wrapper.swig b/lldb/scripts/Python/python-wrapper.swig --- a/lldb/scripts/Python/python-wrapper.swig +++ b/lldb/scripts/Python/python-wrapper.swig @@ -61,20 +61,24 @@ if (!pfunc.IsAllocated()) return stop_at_breakpoint; + unsigned max_positional_args = PythonCallable::ArgInfo::UNBOUNDED; + if (auto arg_info = pfunc.GetArgInfo()) { + max_positional_args = arg_info.get().max_positional_args; + } else { + llvm::consumeError(arg_info.takeError()); + } + PythonObject frame_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_frame)); PythonObject bp_loc_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_bp_loc)); PythonObject result; // If the called function doesn't take extra_args, drop them here: - auto arg_info = pfunc.GetNumArguments(); - if (arg_info.count == 3) - result = pfunc(frame_arg, bp_loc_arg, dict); - else if (arg_info.count == 4) { + if (max_positional_args < 4) { + result = pfunc(frame_arg, bp_loc_arg, dict); + } else { lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl); PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(args_value)); - result = pfunc(frame_arg, bp_loc_arg, args_arg, dict); - } else { - return stop_at_breakpoint; + result = pfunc(frame_arg, bp_loc_arg, args_arg, dict); } if (result.get() == Py_False) diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -782,10 +782,9 @@ return m_sys_module_dict; } -llvm::Expected -ScriptInterpreterPythonImpl::GetNumFixedArgumentsForCallable( - const llvm::StringRef &callable_name) -{ +llvm::Expected +ScriptInterpreterPythonImpl::GetMaxPositionalArgumentsForCallable( + const llvm::StringRef &callable_name) { if (callable_name.empty()) { return llvm::createStringError( llvm::inconvertibleErrorCode(), @@ -796,16 +795,15 @@ Locker::NoSTDIN); auto dict = PythonModule::MainModule() .ResolveName(m_dictionary_name); - auto pfunc - = PythonObject::ResolveNameWithDictionary(callable_name, - dict); + auto pfunc = PythonObject::ResolveNameWithDictionary( + callable_name, dict); if (!pfunc.IsAllocated()) { return llvm::createStringError( llvm::inconvertibleErrorCode(), "can't find callable: %s", callable_name.str().c_str()); } PythonCallable::ArgInfo arg_info = pfunc.GetNumArguments(); - return arg_info.count; + return arg_info.max_positional_args; } static std::string GenerateUniqueName(const char *base_name_wanted, @@ -1232,22 +1230,22 @@ // For now just cons up a oneliner that calls the provided function. std::string oneliner("return "); oneliner += function_name; - - llvm::Expected maybe_args - = GetNumFixedArgumentsForCallable(function_name); + + llvm::Expected maybe_args = + GetMaxPositionalArgumentsForCallable(function_name); if (!maybe_args) { - error.SetErrorStringWithFormat("could not get num args: %s", + error.SetErrorStringWithFormat( + "could not get num args: %s", llvm::toString(maybe_args.takeError()).c_str()); return error; } - size_t num_args = *maybe_args; - + size_t max_args = *maybe_args; + bool uses_extra_args = false; - if (num_args == 4) { + if (max_args >= 4) { uses_extra_args = true; oneliner += "(frame, bp_loc, extra_args, internal_dict)"; - } - else if (num_args == 3) { + } else if (max_args >= 3) { if (extra_args_sp) { error.SetErrorString("cannot pass extra_args to a three argument callback" ); @@ -1257,12 +1255,12 @@ oneliner += "(frame, bp_loc, internal_dict)"; } else { error.SetErrorStringWithFormat("expected 3 or 4 argument " - "function, %s has %zu", - function_name, num_args); + "function, %s can only take %zu", + function_name, max_args); return error; } - - SetBreakpointCommandCallback(bp_options, oneliner.c_str(), extra_args_sp, + + SetBreakpointCommandCallback(bp_options, oneliner.c_str(), extra_args_sp, uses_extra_args); return error; } @@ -1840,8 +1838,7 @@ StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan( const char *class_name, StructuredDataImpl *args_data, - std::string &error_str, - lldb::ThreadPlanSP thread_plan_sp) { + std::string &error_str, lldb::ThreadPlanSP thread_plan_sp) { if (class_name == nullptr || class_name[0] == '\0') return StructuredData::ObjectSP(); @@ -2145,7 +2142,7 @@ std::string auto_generated_function_name(GenerateUniqueName( "lldb_autogen_python_bp_callback_func_", num_created_functions)); - if (has_extra_args) + if (has_extra_args) sstr.Printf("def %s (frame, bp_loc, extra_args, internal_dict):", auto_generated_function_name.c_str()); else diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h @@ -256,11 +256,10 @@ BreakpointOptions *bp_options, std::unique_ptr &data_up) override; - Status SetBreakpointCommandCallback( - BreakpointOptions *bp_options, - const char *command_body_text, - StructuredData::ObjectSP extra_args_sp, - bool uses_extra_args); + Status SetBreakpointCommandCallback(BreakpointOptions *bp_options, + const char *command_body_text, + StructuredData::ObjectSP extra_args_sp, + bool uses_extra_args); /// Set a one-liner as the callback for the watchpoint. void SetWatchpointCommandCallback(WatchpointOptions *wp_options, @@ -378,10 +377,9 @@ python::PythonDictionary &GetSessionDictionary(); python::PythonDictionary &GetSysModuleDictionary(); - - llvm::Expected - GetNumFixedArgumentsForCallable(const llvm::StringRef &callable_name) - override; + + llvm::Expected GetMaxPositionalArgumentsForCallable( + const llvm::StringRef &callable_name) override; bool GetEmbeddedInterpreterModuleObjects();