Skip to content

Commit a7030f5

Browse files
committed
feat: add new call logging
1 parent 11fb35f commit a7030f5

4 files changed

Lines changed: 59 additions & 40 deletions

File tree

CMakeLists.txt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,12 @@ endif()
179179
target_link_libraries(${PROJECT_NAME} PRIVATE python3)
180180

181181
target_compile_definitions(${PROJECT_NAME} PRIVATE
182-
PY3LM_PLATFORM_WINDOWS=$<BOOL:${WIN32}>
183-
PY3LM_PLATFORM_APPLE=$<BOOL:${APPLE}>
184-
PY3LM_PLATFORM_LINUX=$<BOOL:${LINUX}>
185-
PY3LM_IS_DEBUG=$<STREQUAL:${CMAKE_BUILD_TYPE},Debug>)
182+
PY3LM_PLATFORM_WINDOWS=$<BOOL:${WIN32}>
183+
PY3LM_PLATFORM_APPLE=$<BOOL:${APPLE}>
184+
PY3LM_PLATFORM_LINUX=$<BOOL:${LINUX}>
185+
PY3LM_IS_DEBUG=$<STREQUAL:${CMAKE_BUILD_TYPE},Debug>
186+
PY3LM_IS_RELEASE=$<STREQUAL:${CMAKE_BUILD_TYPE},Release>
187+
)
186188

187189
configure_file(
188190
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pmodule.in

src/module.cpp

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
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;

src/module.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include <plugify/callback.hpp>
44
#include <plugify/call.hpp>
55
#include <plugify/language_module.hpp>
6+
#include <plugify/logger.hpp>
7+
#include <plugify/provider.hpp>
68
#include <plugify/extension.hpp>
79

810
#include <plg/numerics.hpp>
@@ -155,6 +157,8 @@ namespace py3lm {
155157
std::vector<std::string> ExtractRequiredModules(std::string_view modulePath);
156158

157159
const std::unique_ptr<Provider>& GetProvider() const { return _provider; }
160+
const std::shared_ptr<ILogger>& GetLogger() const { return _logger; }
161+
158162
void LogFatal(std::string_view msg) const;
159163
void LogError() const;
160164

@@ -166,6 +170,7 @@ namespace py3lm {
166170

167171
private:
168172
std::unique_ptr<Provider> _provider;
173+
std::shared_ptr<ILogger> _logger;
169174
struct PluginData {
170175
PyObject* module = nullptr;
171176
PyObject* instance = nullptr;

0 commit comments

Comments
 (0)