implement Logger API for Lua

This commit is contained in:
falsycat 2022-07-02 23:15:33 +09:00
parent cc883c5f36
commit b1117ccea9
5 changed files with 69 additions and 33 deletions

View File

@ -2,6 +2,7 @@
#include <cassert>
#include <memory>
#include <source_location>
#include <string_view>
#include "nf7.hh"
@ -35,17 +36,17 @@ class LoggerRef final {
}
// thread-safe
void Trace(std::string_view msg) noexcept {
Write({nf7::Logger::kTrace, msg});
void Trace(std::string_view msg, std::source_location s = std::source_location::current()) noexcept {
Write({nf7::Logger::kTrace, msg, 0, s});
}
void Info(std::string_view msg) noexcept {
Write({nf7::Logger::kInfo, msg});
void Info(std::string_view msg, std::source_location s = std::source_location::current()) noexcept {
Write({nf7::Logger::kInfo, msg, 0, s});
}
void Warn(std::string_view msg) noexcept {
Write({nf7::Logger::kWarn, msg});
void Warn(std::string_view msg, std::source_location s = std::source_location::current()) noexcept {
Write({nf7::Logger::kWarn, msg, 0, s});
}
void Error(std::string_view msg) noexcept {
Write({nf7::Logger::kError, msg});
void Error(std::string_view msg, std::source_location s = std::source_location::current()) noexcept {
Write({nf7::Logger::kError, msg, 0, s});
}
void Write(nf7::Logger::Item&& item) noexcept {
if (!id_ || !logger_) return;

View File

@ -4,6 +4,10 @@
#include <lua.hpp>
#include "common/logger.hh"
#include "common/logger_ref.hh"
#include "common/luajit_thread.hh"
namespace nf7::luajit {

View File

@ -28,22 +28,9 @@ inline void PushWeakPtr(lua_State* L, const std::weak_ptr<T>& wptr) noexcept {
new (lua_newuserdata(L, sizeof(wptr))) std::weak_ptr<T>(wptr);
}
template <typename T>
inline std::weak_ptr<T>& ToWeakPtr(lua_State* L, int idx) {
std::weak_ptr<T>* wptr = reinterpret_cast<decltype(wptr)>(lua_touserdata(L, idx));
return *wptr;
}
template <typename T>
inline std::shared_ptr<T> ToSharedPtr(lua_State* L, int idx) {
if (auto ret = ToWeakPtr<T>(L, idx).lock()) {
return ret;
}
luaL_error(L, "object expired: %s", typeid(T).name());
return nullptr;
}
template <typename T>
inline void PushWeakPtrDeleter(lua_State* L, const std::weak_ptr<T>& = {}) {
inline void PushWeakPtrDeleter(lua_State* L, const std::weak_ptr<T>& = {}) noexcept {
lua_pushcfunction(L, [](auto L) {
ToWeakPtr<T>(L, 1).~weak_ptr();
reinterpret_cast<std::weak_ptr<T>*>(lua_touserdata(L, 1))->~weak_ptr();
return 0;
});
}
@ -55,12 +42,21 @@ inline bool MatchMetaName(lua_State* L, int idx, const char* type) noexcept {
lua_pop(L, 2);
return ret;
}
template <typename T>
inline T* ToRef(lua_State* L, int idx, const char* type) noexcept {
return MatchMetaName(L, idx, type)? reinterpret_cast<T*>(lua_touserdata(L, idx)): nullptr;
}
template <typename T>
inline std::shared_ptr<T> CheckWeakPtr(lua_State* L, int idx, const char* type) {
auto ptr = reinterpret_cast<std::weak_ptr<T>*>(luaL_checkudata(L, idx, type));
if (auto ret = ptr->lock()) {
return ret;
} else {
luaL_error(L, "object expired: %s", typeid(T).name());
return nullptr;
}
}
template <typename T>
inline T& CheckRef(lua_State* L, int idx, const char* type) {
return *reinterpret_cast<T*>(luaL_checkudata(L, idx, type));

View File

@ -1,9 +1,12 @@
#include "common/luajit_thread.hh"
#include <sstream>
namespace nf7::luajit {
constexpr size_t kInstructionLimit = 10000000;
constexpr const char* kTypeName = "nf7::luajit::Thread";
constexpr size_t kInstructionLimit = 10000000;
Thread::~Thread() noexcept {
@ -11,19 +14,41 @@ Thread::~Thread() noexcept {
}
void Thread::PushMeta(lua_State* L) noexcept {
if (luaL_newmetatable(L, "nf7::luajit::Thread")) {
if (luaL_newmetatable(L, kTypeName)) {
PushWeakPtrDeleter<Thread>(L);
lua_setfield(L, -2, "__gc");
lua_createtable(L, 0, 0);
{
lua_pushcfunction(L, [](auto L) {
auto th = ToSharedPtr<Thread>(L, 1);
auto th = CheckWeakPtr<Thread>(L, 1, kTypeName);
th->ExpectYield();
th->ExecResume(L);
return lua_yield(L, lua_gettop(L)-1);
});
lua_setfield(L, -2, "yield");
static const auto log_write = [](lua_State* L, nf7::Logger::Level lv) {
auto th = CheckWeakPtr<Thread>(L, 1, kTypeName);
auto logger = th->logger_;
if (!logger) return luaL_error(L, "logger is not installed on current thread");
const int n = lua_gettop(L);
std::stringstream st;
for (int i = 2; i <= n; ++i) {
st << lua_tostring(L, i);
}
logger->Write({lv, st.str()});
return 0;
};
lua_pushcfunction(L, [](auto L) { return log_write(L, nf7::Logger::kTrace); });
lua_setfield(L, -2, "trace");
lua_pushcfunction(L, [](auto L) { return log_write(L, nf7::Logger::kInfo); });
lua_setfield(L, -2, "info");
lua_pushcfunction(L, [](auto L) { return log_write(L, nf7::Logger::kWarn); });
lua_setfield(L, -2, "warn");
lua_pushcfunction(L, [](auto L) { return log_write(L, nf7::Logger::kError); });
lua_setfield(L, -2, "error");
}
lua_setfield(L, -2, "__index");
}

View File

@ -13,6 +13,7 @@
#include "nf7.hh"
#include "common/future.hh"
#include "common/logger_ref.hh"
#include "common/luajit.hh"
#include "common/luajit_ref.hh"
#include "common/proxy_env.hh"
@ -51,6 +52,11 @@ class Thread final : public std::enable_shared_from_this<Thread> {
Thread& operator=(const Thread&) = delete;
Thread& operator=(Thread&&) = delete;
void Install(const std::shared_ptr<nf7::LoggerRef>& logger) noexcept {
assert(state_ == kInitial);
logger_ = logger;
}
// must be called on luajit thread
lua_State* Init(lua_State* L) noexcept {
assert(state_ == kInitial);
@ -72,6 +78,12 @@ class Thread final : public std::enable_shared_from_this<Thread> {
ljq_->Push(ctx_, [this, L, self = shared_from_this()](auto) { Resume(L, 0); });
}
// must be called on luajit thread
// handler_ won't be called on next yielding
void ExpectYield() noexcept {
skip_handle_ = true;
}
// thread-safe
void Abort() noexcept;
@ -82,12 +94,6 @@ class Thread final : public std::enable_shared_from_this<Thread> {
}
}
// must be called on luajit thread
// handler_ won't be called on next yielding
void ExpectYield() noexcept {
skip_handle_ = true;
}
nf7::Env& env() noexcept { return env_; }
const std::shared_ptr<nf7::Context>& ctx() const noexcept { return ctx_; }
const std::shared_ptr<nf7::luajit::Queue>& ljq() const noexcept { return ljq_; }
@ -109,6 +115,10 @@ class Thread final : public std::enable_shared_from_this<Thread> {
std::optional<nf7::luajit::Ref> th_ref_;
// installed features
std::shared_ptr<nf7::LoggerRef> logger_;
// mutable params
Holder* holder_ = nullptr;