55#include < bitset>
66#include < exception>
77
8- #include < plugify/logger.hpp>
9- #include < plugify/provider.hpp>
10-
118#include < plg/string.hpp>
129#include < plg/any.hpp>
1310#include < plg/format.hpp>
@@ -2770,6 +2767,19 @@ namespace py3lm {
27702767 }
27712768 }
27722769
2770+ void TraceCall (std::string_view message) {
2771+ if (const auto & logger = g_py3lm.GetLogger ()/* ; logger && logger->GetLogLevel() <= Severity::Debug*/ ) {
2772+ PyFrameObject* frame = PyEval_GetFrame ();
2773+ size_t line = static_cast <size_t >(PyFrame_GetLineNumber (frame));
2774+ PyCodeObject* code = PyFrame_GetCode (frame);
2775+ const auto fileName = PyUnicode_AsString (code->co_filename );
2776+ const auto functionName = PyUnicode_AsString (code->co_name );
2777+ const auto moduleName = PyUnicode_AsUTF8 (code->co_qualname );
2778+ logger->Log (message, Severity::Trace, Location (line, 0 , fileName, functionName, moduleName));
2779+ Py_DECREF (code);
2780+ }
2781+ }
2782+
27732783 // PyObject* (MethodPyCall*)(PyObject* self, PyObject* args)
27742784 void ExternalCallNoArgs (const Method* method, MemAddr data, [[maybe_unused]] uint64_t * parameters, [[maybe_unused]] size_t count, void * return_) {
27752785 // ParametersSpan params(parameters, count);
@@ -2778,6 +2788,8 @@ namespace py3lm {
27782788 const Property& retType = method->GetRetType ();
27792789 const bool hasHiddenParam = ValueUtils::IsHiddenParam (retType.GetType ());
27802790
2791+ TraceCall (method->GetName ());
2792+
27812793 ArgsScope a (hasHiddenParam);
27822794 Return r;
27832795
@@ -2800,26 +2812,22 @@ namespace py3lm {
28002812 ParametersSpan params (parameters, count);
28012813 ReturnSlot ret (return_, ValueUtils::SizeOf (ValueType::Pointer));
28022814
2803- // PyObject* (MethodPyCall*)(PyObject* self, PyObject* args)
2804- const auto args = params.Get <PyObject*>(1 );
2805-
2806- if (!PyTuple_Check (args)) {
2807- const std::string error (std::format (" Function \" {}\" expects a tuple of arguments" , method->GetFuncName ()));
2808- SetTypeError (error, args);
2809- ret.Set <void *>(nullptr );
2810- return ;
2811- }
2815+ // PyObject* (MethodPyCall*)(PyObject* self, PyObject *const *args, Py_ssize_t nargs)
2816+ const auto args = params.Get <PyObject *const *>(1 );
2817+ const auto nargs = params.Get <Py_ssize_t>(2 );
28122818
28132819 const auto & paramTypes = method->GetParamTypes ();
28142820 const auto paramCount = paramTypes.size ();
2815- const size_t size = static_cast <size_t >(PyTuple_Size (args) );
2821+ const size_t size = static_cast <size_t >(nargs );
28162822 if (size != paramCount) {
28172823 const std::string error (std::format (" Wrong number of parameters, {} when {} required." , size, paramCount));
28182824 PyErr_SetString (PyExc_TypeError, error.c_str ());
28192825 ret.Set <void *>(nullptr );
28202826 return ;
28212827 }
28222828
2829+ TraceCall (method->GetName ());
2830+
28232831 const Property& retType = method->GetRetType ();
28242832 const bool hasHiddenParam = ValueUtils::IsHiddenParam (retType.GetType ());
28252833 Py_ssize_t refParamsCount = 0 ;
@@ -2838,7 +2846,7 @@ namespace py3lm {
28382846 }
28392847 using PushParamFunc = bool (*)(const Property&, PyObject*, ArgsScope&);
28402848 PushParamFunc const pushParamFunc = paramType.IsRef () ? &PushObjectAsRefParam : &PushObjectAsParam;
2841- const bool pushResult = pushParamFunc (paramType, PyTuple_GetItem ( args, static_cast <Py_ssize_t>(i)) , a);
2849+ const bool pushResult = pushParamFunc (paramType, args[ static_cast <Py_ssize_t>(i)] , a);
28422850 if (!pushResult) {
28432851 // pushParamFunc set error
28442852 ret.Set <void *>(nullptr );
@@ -3002,7 +3010,7 @@ namespace py3lm {
30023010 PyObject* func = PyDict_GetItemString (moduleDict, methodName.c_str ());
30033011 if (!func) {
30043012 PyErr_Clear ();
3005- g_py3lm.GetProvider ()->Log (std::format (LOG_PREFIX " Method function not found: {}" , binding.GetMethod ()), Severity::Fatal);
3013+ g_py3lm.GetLogger ()->Log (std::format (LOG_PREFIX " Method function not found: {}" , binding.GetMethod ()), Severity::Fatal);
30063014 Py_DECREF (tuple);
30073015 return nullptr ;
30083016 }
@@ -3056,7 +3064,7 @@ namespace py3lm {
30563064 return nullptr ;
30573065 }
30583066
3059- g_py3lm.GetProvider ()->Log (PyUnicode_AsString (message), Severity::Unknown);
3067+ g_py3lm.GetLogger ()->Log (PyUnicode_AsString (message), Severity::Unknown);
30603068
30613069 Py_DECREF (message);
30623070
@@ -3071,6 +3079,7 @@ namespace py3lm {
30713079
30723080 Result<InitData> Python3LanguageModule::Initialize (const Provider& provider, const Extension& module ) {
30733081 _provider = std::make_unique<Provider>(provider);
3082+ _logger = _provider->Resolve <ILogger>();
30743083
30753084 std::error_code ec;
30763085 const fs::path moduleBasePath = fs::absolute (module .GetLocation (), ec);
@@ -3424,6 +3433,7 @@ namespace py3lm {
34243433 _moduleFunctions.clear ();
34253434 _pythonMethods.clear ();
34263435 _pluginsMap.clear ();
3436+ _logger.reset ();
34273437 _provider.reset ();
34283438 }
34293439
@@ -3543,7 +3553,7 @@ namespace py3lm {
35433553 std::string moduleName = filePathRelative.generic_string ();
35443554 ReplaceAll (moduleName, " /" , " ." );
35453555
3546- _provider ->Log (std::format (LOG_PREFIX " Load plugin module '{}'" , moduleName), Severity::Verbose );
3556+ _logger ->Log (std::format (LOG_PREFIX " Load plugin module '{}'" , moduleName), Severity::Debug );
35473557
35483558 GILLock lock{};
35493559
@@ -3732,7 +3742,7 @@ namespace py3lm {
37323742 PyObject* const returnObject = PyObject_CallNoArgs (plugin.GetUserData ().RCast <PluginData*>()->start );
37333743 if (!returnObject) {
37343744 LogError ();
3735- _provider ->Log (std::format (LOG_PREFIX " {}: call of 'plugin_start' failed" , plugin.GetName ()), Severity::Error);
3745+ _logger ->Log (std::format (LOG_PREFIX " {}: call of 'plugin_start' failed" , plugin.GetName ()), Severity::Error);
37363746 }
37373747 Py_DECREF (returnObject);
37383748 }
@@ -3744,7 +3754,7 @@ namespace py3lm {
37443754 Py_DECREF (deltaTime);
37453755 if (!returnObject) {
37463756 LogError ();
3747- _provider ->Log (std::format (LOG_PREFIX " {}: call of 'plugin_update' failed" , plugin.GetName ()), Severity::Error);
3757+ _logger ->Log (std::format (LOG_PREFIX " {}: call of 'plugin_update' failed" , plugin.GetName ()), Severity::Error);
37483758 }
37493759 Py_DECREF (returnObject);
37503760 }
@@ -3754,7 +3764,7 @@ namespace py3lm {
37543764 PyObject* const returnObject = PyObject_CallNoArgs (plugin.GetUserData ().RCast <PluginData*>()->end );
37553765 if (!returnObject) {
37563766 LogError ();
3757- _provider ->Log (std::format (LOG_PREFIX " {}: call of 'plugin_end' failed" , plugin.GetName ()), Severity::Error);
3767+ _logger ->Log (std::format (LOG_PREFIX " {}: call of 'plugin_end' failed" , plugin.GetName ()), Severity::Error);
37583768 }
37593769 Py_DECREF (returnObject);
37603770 }
@@ -3800,13 +3810,14 @@ namespace py3lm {
38003810
38013811 JitCallback callback{};
38023812
3813+ const bool noArgs = method.GetParamTypes ().empty ();
3814+
38033815 Signature sig{};
38043816 sig.AddArg (ValueType::Pointer);
38053817 sig.AddArg (ValueType::Pointer);
3818+ if (!noArgs) sig.AddArg (ValueType::Pointer);
38063819 sig.SetRet (ValueType::Pointer);
38073820
3808- const bool noArgs = method.GetParamTypes ().empty ();
3809-
38103821 const MemAddr methodAddr = callback.GetJitFunc (sig, &method, noArgs ? &ExternalCallNoArgs : &ExternalCall, callAddr, false );
38113822 if (!methodAddr) {
38123823 const std::string error (std::format (" Lang module JIT failed to generate c++ PyCFunction wrapper '{}'" , callback.GetError ()));
@@ -3818,7 +3829,7 @@ namespace py3lm {
38183829 PyMethodDef& def = *(defPtr);
38193830 def.ml_name = " PlugifyExternal" ;
38203831 def.ml_meth = methodAddr.RCast <PyCFunction>();
3821- def.ml_flags = noArgs ? METH_NOARGS : METH_VARARGS ;
3832+ def.ml_flags = noArgs ? METH_NOARGS : METH_FASTCALL ;
38223833 def.ml_doc = nullptr ;
38233834
38243835 PyObject* const object = PyCFunction_New (defPtr.get (), nullptr );
@@ -4236,7 +4247,7 @@ namespace py3lm {
42364247 for (const auto & [method, addr] : plugin.GetMethodsData ()) {
42374248 PyObject* const methodObject = FindPythonMethod (addr);
42384249 if (!methodObject) {
4239- _provider ->Log (std::format (LOG_PREFIX " Not found '{}' method while CreateInternalModule for '{}' plugin" , method.GetName (), plugin.GetName ()), Severity::Fatal);
4250+ _logger ->Log (std::format (LOG_PREFIX " Not found '{}' method while CreateInternalModule for '{}' plugin" , method.GetName (), plugin.GetName ()), Severity::Fatal);
42404251 std::terminate ();
42414252 }
42424253 [[maybe_unused]] const auto res = PyDict_SetItemString (moduleDict, method.GetName ().c_str (), methodObject);
@@ -4259,30 +4270,31 @@ namespace py3lm {
42594270
42604271 const MemAddr callAddr = call.GetJitFunc (method, addr);
42614272 if (!callAddr) {
4262- _provider ->Log (std::format (LOG_PREFIX " Lang module JIT failed to generate c++ call wrapper '{}'" , call.GetError ()), Severity::Fatal);
4273+ _logger ->Log (std::format (LOG_PREFIX " Lang module JIT failed to generate c++ call wrapper '{}'" , call.GetError ()), Severity::Fatal);
42634274 std::terminate ();
42644275 }
42654276
42664277 JitCallback callback{};
42674278
4279+ const bool noArgs = method.GetParamTypes ().empty ();
4280+
42684281 Signature sig{};
42694282 sig.AddArg (ValueType::Pointer);
42704283 sig.AddArg (ValueType::Pointer);
4284+ if (!noArgs) sig.AddArg (ValueType::Pointer);
42714285 sig.SetRet (ValueType::Pointer);
42724286
4273- const bool noArgs = method.GetParamTypes ().empty ();
4274-
42754287 // Generate function --> PyObject* (MethodPyCall*)(PyObject* self, PyObject* args)
42764288 const MemAddr methodAddr = callback.GetJitFunc (sig, &method, noArgs ? &ExternalCallNoArgs : &ExternalCall, callAddr, false );
42774289 if (!methodAddr) {
4278- _provider ->Log (std::format (LOG_PREFIX " Lang module JIT failed to generate c++ PyCFunction wrapper '{}'" , callback.GetError ()), Severity::Fatal);
4290+ _logger ->Log (std::format (LOG_PREFIX " Lang module JIT failed to generate c++ PyCFunction wrapper '{}'" , callback.GetError ()), Severity::Fatal);
42794291 std::terminate ();
42804292 }
42814293
42824294 PyMethodDef& def = moduleMethods.emplace_back ();
42834295 def.ml_name = method.GetName ().c_str ();
42844296 def.ml_meth = methodAddr.RCast <PyCFunction>();
4285- def.ml_flags = noArgs ? METH_NOARGS : METH_VARARGS ;
4297+ def.ml_flags = noArgs ? METH_NOARGS : METH_FASTCALL ;
42864298 def.ml_doc = nullptr ;
42874299
42884300 _moduleFunctions.emplace_back (std::move (callback), std::move (call));
@@ -4359,7 +4371,7 @@ namespace py3lm {
43594371 PyObject* constructorFunc = PyDict_GetItemString (moduleDict, constructorNames[i].c_str ());
43604372 if (!constructorFunc) {
43614373 PyErr_Clear ();
4362- _provider ->Log (std::format (LOG_PREFIX " Constructor function not found: {}" , constructorNames[i]), Severity::Fatal);
4374+ _logger ->Log (std::format (LOG_PREFIX " Constructor function not found: {}" , constructorNames[i]), Severity::Fatal);
43634375 return ;
43644376 }
43654377 Py_INCREF (constructorFunc);
@@ -4373,7 +4385,7 @@ namespace py3lm {
43734385 destructorFunc = PyDict_GetItemString (moduleDict, destructorName.c_str ());
43744386 if (!destructorFunc) {
43754387 PyErr_Print ();
4376- _provider ->Log (std::format (LOG_PREFIX " Destructor function not found: {}" , destructorName), Severity::Fatal);
4388+ _logger ->Log (std::format (LOG_PREFIX " Destructor function not found: {}" , destructorName), Severity::Fatal);
43774389 return ;
43784390 }
43794391 } else {
@@ -4437,7 +4449,7 @@ namespace py3lm {
44374449
44384450 if (!result) {
44394451 LogError ();
4440- _provider ->Log (std::format (LOG_PREFIX " {}: call of 'bind_class_methods' failed" , className), Severity::Error);
4452+ _logger ->Log (std::format (LOG_PREFIX " {}: call of 'bind_class_methods' failed" , className), Severity::Error);
44414453 return ;
44424454 }
44434455
@@ -4550,7 +4562,7 @@ namespace py3lm {
45504562 Py_DECREF (pvalue);
45514563 Py_DECREF (ptraceback);
45524564 if (!strList) {
4553- _provider ->Log (" Couldn't get exact error message" , Severity::Error);
4565+ _logger ->Log (" Couldn't get exact error message" , Severity::Error);
45544566 return ;
45554567 }
45564568
@@ -4572,11 +4584,11 @@ namespace py3lm {
45724584
45734585 Py_DECREF (strList);
45744586
4575- _provider ->Log (result, Severity::Error);
4587+ _logger ->Log (result, Severity::Error);
45764588 }
45774589
45784590 void Python3LanguageModule::LogFatal (std::string_view msg) const {
4579- _provider ->Log (msg, Severity::Fatal);
4591+ _logger ->Log (msg, Severity::Fatal);
45804592 }
45814593
45824594 Python3LanguageModule g_py3lm;
0 commit comments