Skip to content

Commit bb6f0bb

Browse files
committed
fix: add initial work for class generation
1 parent 4d99722 commit bb6f0bb

File tree

2 files changed

+165
-26
lines changed

2 files changed

+165
-26
lines changed

src/module.cpp

Lines changed: 155 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2988,19 +2988,142 @@ namespace lualm {
29882988
}
29892989
}
29902990

2991-
std::vector<luaL_Reg> LuaLanguageModule::CreateFunctions(const Extension& plugin) {
2991+
void LuaLanguageModule::PushInvalidValue(ValueType handleType, std::string_view invalidValue) {
2992+
//TODO
2993+
}
2994+
2995+
void LuaLanguageModule::PushAlias(const Alias& alias) {
2996+
if (alias.GetName().empty()) {
2997+
lua_pushnil(_L);
2998+
return;
2999+
}
3000+
3001+
lua_createtable(_L, 2, 0);
3002+
3003+
// [1] = name
3004+
lua_pushstring(_L, alias.GetName().c_str());
3005+
lua_rawseti(_L, -2, 1);
3006+
3007+
// [2] = owner
3008+
lua_pushboolean(_L, alias.IsOwner());
3009+
lua_rawseti(_L, -2, 2);
3010+
}
3011+
3012+
void LuaLanguageModule::PushBinding(const LuaFunctionMap& functions, const Binding& binding) {
3013+
lua_createtable(_L, 5, 0);
3014+
3015+
// [1] = name
3016+
lua_pushstring(_L, binding.GetName().c_str());
3017+
lua_rawseti(_L, -2, 1);
3018+
3019+
// [2] = func
3020+
auto it = functions.find(binding.GetMethod());
3021+
if (it != functions.end()) {
3022+
lua_pushcfunction(_L, it->second);
3023+
} else {
3024+
_provider->Log(std::format(LOG_PREFIX "Method function not found: {}", binding.GetMethod()), Severity::Fatal);
3025+
std::terminate();
3026+
}
3027+
lua_rawseti(_L, -2, 2);
3028+
3029+
// [3] = bindSelf
3030+
lua_pushboolean(_L, binding.IsBindSelf());
3031+
lua_rawseti(_L, -2, 3);
3032+
3033+
// [4] = paramAliases (array of Alias or nil)
3034+
const auto& paramAliases = binding.GetParamAliases();
3035+
lua_createtable(_L, static_cast<int>(paramAliases.size()), 0);
3036+
for (size_t j = 0; j < paramAliases.size(); ++j) {
3037+
PushAlias(paramAliases[j]);
3038+
lua_rawseti(_L, -2, static_cast<int>(j + 1));
3039+
}
3040+
lua_rawseti(_L, -2, 4);
3041+
3042+
// [5] = retAlias (Alias or nil)
3043+
PushAlias(binding.GetRetAlias());
3044+
lua_rawseti(_L, -2, 5);
3045+
}
3046+
3047+
void LuaLanguageModule::CreateClassObject(const LuaFunctionMap& functions, const Class& cls) {
3048+
const std::string& className = cls.GetName();
3049+
3050+
// Create class table
3051+
lua_newtable(_L);
3052+
lua_pushstring(_L, className.c_str());
3053+
lua_setfield(_L, -2, "__name");
3054+
int cls_table_idx = lua_gettop(_L);
3055+
3056+
// Call bind_class_methods(cls, constructors, destructor, methods, invalid_value)
3057+
lua_pushvalue(_L, _bindClassFunc); // Push bind_class_methods function
3058+
3059+
// Arg 1: cls (the class table)
3060+
lua_pushvalue(_L, cls_table_idx);
3061+
3062+
// Arg 2: constructors (array of functions)
3063+
const auto& constructors = cls.GetConstructors();
3064+
lua_createtable(_L, static_cast<int>(constructors.size()), 0);
3065+
for (size_t i = 0; i < constructors.size(); ++i) {
3066+
auto it = functions.find(constructors[i]);
3067+
if (it != functions.end()) {
3068+
lua_pushcfunction(_L, it->second);
3069+
lua_rawseti(_L, -2, static_cast<int>(i + 1));
3070+
} else {
3071+
_provider->Log(std::format(LOG_PREFIX "Constructor function not found: {}", constructors[i]), Severity::Fatal);
3072+
std::terminate();
3073+
}
3074+
}
3075+
3076+
// Arg 3: destructor (function or nil)
3077+
const std::string& destructor = cls.GetDestructor();
3078+
if (!destructor.empty()) {
3079+
auto it = functions.find(destructor);
3080+
if (it != functions.end()) {
3081+
lua_pushcfunction(_L, it->second);
3082+
} else {
3083+
_provider->Log(std::format(LOG_PREFIX "Destructor function not found: {}", destructor), Severity::Fatal);
3084+
std::terminate();
3085+
}
3086+
} else {
3087+
lua_pushnil(_L);
3088+
}
3089+
3090+
// Arg 4: methods (array of {name, func, bindSelf, paramAliases, retAlias})
3091+
const auto& bindings = cls.GetBindings();
3092+
lua_createtable(_L, static_cast<int>(bindings.size()), 0);
3093+
for (size_t i = 0; i < bindings.size(); ++i) {
3094+
PushBinding(functions, bindings[i]);
3095+
lua_rawseti(_L, -2, static_cast<int>(i + 1));
3096+
}
3097+
3098+
// Arg 5: invalid_value
3099+
PushInvalidValue(cls.GetHandleType(), cls.GetInvalidValue());
3100+
3101+
// Call: bind_class_methods(cls, constructors, destructor, methods, invalid_value)
3102+
if (lua_pcall(_L, 5, 1, 0) != LUA_OK) {
3103+
LogError();
3104+
_provider->Log(std::format(LOG_PREFIX "{}: call of 'bind_class_methods' failed", className), Severity::Error);
3105+
lua_pop(_L, 1);
3106+
lua_pop(_L, 1); // Pop class table
3107+
return;
3108+
}
3109+
3110+
lua_setfield(_L, -2, className.data());
3111+
}
3112+
3113+
LuaFunctionMap LuaLanguageModule::CreateFunctions(const Extension& plugin) {
29923114
const auto& methods = plugin.GetMethodsData();
29933115

2994-
std::vector<luaL_Reg> funcs;
2995-
funcs.reserve(methods.size() + 1);
3116+
LuaFunctionMap funcs;
3117+
funcs.reserve(methods.size());
29963118

29973119
for (const auto& [method, addr] : methods) {
29983120
JitCall call{};
29993121

30003122
const MemAddr callAddr = call.GetJitFunc(method, addr);
30013123
if (!callAddr) {
3002-
luaL_error(_L, "Lang module JIT failed to generate c++ call wrapper '%s'", call.GetError());
3003-
return funcs;
3124+
_provider->Log(std::format(LOG_PREFIX "Lang module JIT failed to generate c++ call wrapper '{}'", call.GetError()), Severity::Fatal);
3125+
std::terminate();
3126+
return {};
30043127
}
30053128

30063129
JitCallback callback{};
@@ -3012,16 +3135,16 @@ namespace lualm {
30123135
// Generate function --> int (MethodLuaCall*)(lua_State* L)
30133136
const MemAddr methodAddr = callback.GetJitFunc(sig, &method, &detail::ExternalCall, callAddr, false);
30143137
if (!methodAddr) {
3015-
luaL_error(_L, "Lang module JIT failed to generate c++ lua_CFunction wrapper '%s'", callback.GetError().data());
3016-
return funcs;
3138+
_provider->Log(std::format(LOG_PREFIX "Lang module JIT failed to generate c++ lua_CFunction wrapper '{}'", callback.GetError()), Severity::Fatal);
3139+
std::terminate();
3140+
return {};
30173141
}
30183142

30193143
_moduleFunctions.emplace_back(std::move(callback), std::move(call));
30203144

3021-
funcs.emplace_back(method.GetName().data(), methodAddr.RCast<lua_CFunction>());
3145+
funcs.emplace(method.GetName(), methodAddr.RCast<lua_CFunction>());
30223146
}
30233147

3024-
funcs.emplace_back(nullptr, nullptr); // End of functions
30253148
return funcs;
30263149
}
30273150

@@ -3074,37 +3197,45 @@ namespace lualm {
30743197
// Register our custom require
30753198
lua_pushcfunction(_L, CustomRequire);
30763199
lua_setglobal(_L, "require");
3077-
3078-
// Create a Vector2 instance
3200+
30793201
lua_getglobal(_L, "package"); // Stack: package
30803202
lua_getfield(_L, -1, "loaded"); // Stack: package, loaded
30813203
lua_getfield(_L, -1, "plugify"); // Stack: package, loaded, plugify
30823204

3205+
lua_getfield(_L, -1, "bind_class_methods");
3206+
if (!lua_isfunction(_L, -1)) {
3207+
lua_pop(_L, 4);
3208+
return MakeError("bind_class_methods is not a function");
3209+
}
3210+
3211+
// Stack: package, loaded, bind_class_methods
3212+
_bindClassFunc = luaL_ref(_L, LUA_REGISTRYINDEX); // Store bind_class_methods instance
3213+
30833214
lua_getfield(_L, -1, "Vector2"); // Stack: package, loaded, plugify, Vector2
30843215
lua_getfield(_L, -1, "new"); // Stack: package, loaded, plugify, Vector2, Vector2.new
30853216

3086-
// Stack: package, loaded, vector, Vector2, vector2_instance
3217+
// Stack: package, loaded, Vector2, vector2_instance
30873218
_vector2Ref = luaL_ref(_L, LUA_REGISTRYINDEX); // Store Vector2 instance
30883219
lua_pop(_L, 1);
30893220

30903221
lua_getfield(_L, -1, "Vector3"); // Stack: package, loaded, plugify, Vector3
30913222
lua_getfield(_L, -1, "new"); // Stack: package, loaded, plugify, Vector3, Vector3.new
30923223

3093-
// Stack: package, loaded, vector, Vector3, vector3_instance
3224+
// Stack: package, loaded, Vector3, vector3_instance
30943225
_vector3Ref = luaL_ref(_L, LUA_REGISTRYINDEX); // Store Vector3 instance
30953226
lua_pop(_L, 1);
30963227

30973228
lua_getfield(_L, -1, "Vector4"); // Stack: package, loaded, plugify, Vector4
30983229
lua_getfield(_L, -1, "new"); // Stack: package, loaded, plugify, Vector4, Vector4.new
30993230

3100-
// Stack: package, loaded, vector, Vector4, vector4_instance
3231+
// Stack: package, loaded, Vector4, vector4_instance
31013232
_vector4Ref = luaL_ref(_L, LUA_REGISTRYINDEX); // Store Vector2 instance
31023233
lua_pop(_L, 1);
31033234

31043235
lua_getfield(_L, -1, "Matrix4x4"); // Stack: package, loaded, plugify, Matrix4x4
31053236
lua_getfield(_L, -1, "new"); // Stack: package, loaded, plugify, Matrix4x4, Matrix4x4.new
31063237

3107-
// Stack: package, loaded, vector, Matrix4x4, matrix4x4_instance
3238+
// Stack: package, loaded, Matrix4x4, matrix4x4_instance
31083239
_matrix4x4Ref = luaL_ref(_L, LUA_REGISTRYINDEX); // Store Matrix4x4 instance
31093240
lua_pop(_L, 1);
31103241

@@ -3119,6 +3250,8 @@ namespace lualm {
31193250

31203251
luaL_unref(_L, LUA_REGISTRYINDEX, _originalRequireRef);
31213252
_originalRequireRef = LUA_NOREF;
3253+
luaL_unref(_L, LUA_REGISTRYINDEX, _bindClassFunc);
3254+
_bindClassFunc = LUA_NOREF;
31223255
luaL_unref(_L, LUA_REGISTRYINDEX, _vector2Ref);
31233256
_vector2Ref = LUA_NOREF;
31243257
luaL_unref(_L, LUA_REGISTRYINDEX, _vector3Ref);
@@ -3148,7 +3281,6 @@ namespace lualm {
31483281
_luaMethods.clear();
31493282
_moduleFunctions.clear();
31503283
_loadFunctions.clear();
3151-
_createFunctions.clear();
31523284

31533285
lua_close(_L);
31543286
_L = nullptr;
@@ -3443,21 +3575,20 @@ namespace lualm {
34433575
// load
34443576
luaL_requiref(_L, modname, &LoadEmpty, 0);
34453577

3446-
auto funcs = CreateFunctions(plugin);
3447-
for (const auto& [name, func]: funcs) {
3448-
if (name == nullptr) {
3449-
continue; // Skip end marker
3450-
}
3578+
LuaFunctionMap funcs = CreateFunctions(plugin);
3579+
for (const auto& [name, func] : funcs) {
34513580
lua_pushcfunction(_L, func);
3452-
lua_setfield(_L, -2, name);// module[func_name] = func
3581+
lua_setfield(_L, -2, name.data()); // module[func_name] = func
34533582
}
34543583

34553584
LuaEnumSet enums;
3456-
for (const auto& [method, _] : plugin.GetMethodsData()) {
3585+
for (const auto& method : plugin.GetMethods()) {
34573586
GenerateEnum(enums, method);
34583587
}
34593588

3460-
_createFunctions.emplace_back(std::move(funcs));
3589+
for (const auto& klass : plugin.GetClasses()) {
3590+
CreateClassObject(funcs, klass);
3591+
}
34613592

34623593
lua_pop(_L, 1);
34633594
}

src/module.hpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
#include <plugify/provider.hpp>
1010
#include <plugify/enum_object.hpp>
1111
#include <plugify/enum_value.hpp>
12+
#include <plugify/class.hpp>
13+
#include <plugify/binding.hpp>
14+
#include <plugify/alias.hpp>
1215

1316
#include <plg/any.hpp>
1417
#include <plg/format.hpp>
@@ -55,6 +58,7 @@ namespace lualm {
5558
using LuaInternalMap = std::unordered_map<LuaFunction, void*, plg::pair_hash<int, int>>;
5659
using LuaExternalMap = std::unordered_map<void*, LuaFunction>;
5760
using LuaEnumSet = std::unordered_set<std::string, plg::string_hash, std::equal_to<>>;
61+
using LuaFunctionMap = std::unordered_map<std::string, lua_CFunction>;
5862

5963
struct LuaMethodData {
6064
JitCallback jitCallback;
@@ -133,9 +137,13 @@ namespace lualm {
133137
public:
134138
void GenerateEnum(LuaEnumSet& enumSet, const Property& paramType);
135139
void GenerateEnum(LuaEnumSet& enumSet, const Method& method);
140+
/*void PushInvalidValue(ValueType handleType, std::string_view invalidValue);
141+
void PushAlias(const Alias& alias);
142+
void PushBinding(const LuaFunctionMap& functions, const Binding& binding);*/
143+
void CreateClassObject(const LuaFunctionMap& functions, const Class& cls);
136144
void TryCreateModule(const Extension& plugin, bool empty);
137145
void ResolveRequiredModule(std::string_view moduleName);
138-
std::vector<luaL_Reg> CreateFunctions(const Extension& plugin);
146+
LuaFunctionMap CreateFunctions(const Extension& plugin);
139147
lua_CFunction OpenModule(std::string filename);
140148
void LogError();
141149

@@ -145,6 +153,7 @@ namespace lualm {
145153
private:
146154
std::unique_ptr<Provider> _provider;
147155
lua_State* _L{nullptr};
156+
int _bindClassFunc{LUA_REFNIL};
148157
int _vector2Ref{LUA_REFNIL};
149158
int _vector3Ref{LUA_REFNIL};
150159
int _vector4Ref{LUA_REFNIL};
@@ -167,7 +176,6 @@ namespace lualm {
167176
std::string filename;
168177
};
169178
std::vector<LoadHolder> _loadFunctions;
170-
std::vector<std::vector<luaL_Reg>> _createFunctions;
171179
struct ExternalHolder {
172180
JitCallback jitCallback;
173181
JitCall jitCall;

0 commit comments

Comments
 (0)