From 4e024f1954874ed53d80b4a1b18c3d14c509e31b Mon Sep 17 00:00:00 2001 From: SDraw Date: Tue, 30 May 2023 10:45:49 +0300 Subject: [PATCH] LuaVM value read method Stack size fix for function call with results --- CVRLua/Lua/LuaArgReader.cs | 42 +-------------- CVRLua/Lua/LuaVM.cs | 102 +++++++++++++++++++------------------ CVRLua/LuaHandler.cs | 2 +- 3 files changed, 55 insertions(+), 91 deletions(-) diff --git a/CVRLua/Lua/LuaArgReader.cs b/CVRLua/Lua/LuaArgReader.cs index f6615eb..e5d7a49 100644 --- a/CVRLua/Lua/LuaArgReader.cs +++ b/CVRLua/Lua/LuaArgReader.cs @@ -261,47 +261,7 @@ public void ReadArguments(List p_args) { while(m_currentArgument <= m_argumentsCount) { - if(m_vm.IsNil(m_currentArgument)) - { - p_args.Add(null); - m_currentArgument++; - continue; - } - if(m_vm.IsBoolean(m_currentArgument)) - { - p_args.Add(m_vm.ToBoolean(m_currentArgument)); - m_currentArgument++; - continue; - } - if(m_vm.IsInteger(m_currentArgument)) - { - p_args.Add(m_vm.ToInteger(m_currentArgument)); - m_currentArgument++; - continue; - } - if(m_vm.IsNumber(m_currentArgument)) - { - p_args.Add(m_vm.ToNumber(m_currentArgument)); - m_currentArgument++; - continue; - } - if(m_vm.IsString(m_currentArgument)) - { - p_args.Add(m_vm.ToString(m_currentArgument)); - m_currentArgument++; - continue; - } - if(m_vm.IsObject(m_currentArgument)) - { - object p_obj = null; - if(m_vm.GetObject(ref p_obj, m_currentArgument)) - p_args.Add(p_obj); - else - p_args.Add(null); - m_currentArgument++; - continue; - } - p_args.Add(null); + p_args.Add(m_vm.ReadValue(m_currentArgument)); m_currentArgument++; } } diff --git a/CVRLua/Lua/LuaVM.cs b/CVRLua/Lua/LuaVM.cs index c41be01..15b369d 100644 --- a/CVRLua/Lua/LuaVM.cs +++ b/CVRLua/Lua/LuaVM.cs @@ -64,32 +64,40 @@ internal LuaVM(string p_name = "") // Generic Lua stuff public int GetTop() => LuaInterop.lua_gettop(m_state); - public void SetGlobal(string p_name) => LuaInterop.lua_setglobal(m_state, p_name); + public bool IsBoolean(int p_index) => LuaInterop.lua_isboolean(m_state, p_index); public bool ToBoolean(int p_index) => (LuaInterop.lua_toboolean(m_state, p_index) == 1); public void PushBoolean(bool p_val) => LuaInterop.lua_pushboolean(m_state, p_val ? 1 : 0); + + public bool IsInteger(int p_index) => (LuaInterop.lua_isinteger(m_state, p_index) == 1); + public long ToInteger(int p_index) => LuaInterop.lua_tointeger(m_state, p_index); + public void PushInteger(long p_val) => LuaInterop.lua_pushinteger(m_state, p_val); + public bool IsNumber(int p_index) => LuaInterop.lua_isnumber(m_state, p_index); public double ToNumber(int p_index) => LuaInterop.lua_tonumber(m_state, p_index); public void PushNumber(double p_val) => LuaInterop.lua_pushnumber(m_state, p_val); + public bool IsString(int p_index) => LuaInterop.lua_isstring(m_state, p_index); public string ToString(int p_index) => LuaInterop.lua_tostring(m_state, p_index); public void PushString(string p_str) => LuaInterop.lua_pushstring(m_state, p_str); - public bool IsInteger(int p_index) => (LuaInterop.lua_isinteger(m_state, p_index) == 1); - public long ToInteger(int p_index) => LuaInterop.lua_tointeger(m_state, p_index); - public void PushInteger(long p_val) => LuaInterop.lua_pushinteger(m_state, p_val); - public bool IsLightUserdata(int p_index) => LuaInterop.lua_islightuserdata(m_state, p_index); - public IntPtr ToLightUserdata(int p_index) => LuaInterop.lua_topointer(m_state, p_index); + public bool IsUserdata(int p_index) => LuaInterop.lua_isuserdata(m_state, p_index); public IntPtr ToUserdata(int p_index) => LuaInterop.lua_touserdata(m_state, p_index); + public bool IsNil(int p_index) => LuaInterop.lua_isnil(m_state, p_index); public void PushNil() => LuaInterop.lua_pushnil(m_state); + + public bool IsFunction(int p_index) => LuaInterop.lua_isfunction(m_state, p_index); public void PushFunction(LuaInterop.lua_CFunction p_func) => LuaInterop.lua_pushcfunction(m_state, p_func); // Execution internal void Execute(string p_script) { if((LuaInterop.luaL_loadstring(m_state, p_script) != LuaInterop.LUA_OK) || (LuaInterop.lua_pcall(m_state, 0, 0, 0) != LuaInterop.LUA_OK)) + { LuaLogger.Log(LuaInterop.lua_tostring(m_state, -1)); + LuaInterop.lua_pop(m_state, 1); + } } // Objects push/get @@ -174,7 +182,7 @@ public void CallFunction(int p_ref, params object[] p_args) LuaInterop.lua_pop(m_state, 1); } - public void CallFunctionWithResults(int p_ref, List p_results, params object[] p_args) + public void CallFunction(int p_ref, List p_results, params object[] p_args) { if(LuaInterop.lua_rawgeti(m_state, LuaInterop.LUA_REGISTRYINDEX, p_ref) == LuaInterop.LUA_TFUNCTION) { @@ -189,44 +197,9 @@ public void CallFunctionWithResults(int p_ref, List p_results, params ob else { for(int i = l_top, j = LuaInterop.lua_gettop(m_state); i <= j; i++) - { - if(LuaInterop.lua_isnil(m_state, i)) - { - p_results.Add(null); - continue; - } - if(LuaInterop.lua_isboolean(m_state, i)) - { - p_results.Add(LuaInterop.lua_toboolean(m_state, i) == 1); - continue; - } - if(LuaInterop.lua_isinteger(m_state, i) == 1) - { - p_results.Add(LuaInterop.lua_tointeger(m_state, i)); - continue; - } - if(LuaInterop.lua_isnumber(m_state, i)) - { - p_results.Add(LuaInterop.lua_tonumber(m_state, i)); - continue; - } - if(LuaInterop.lua_isstring(m_state, i)) - { - p_results.Add(LuaInterop.lua_tostring(m_state, i)); - continue; - } - if(LuaInterop.lua_isuserdata(m_state, i)) - { - long l_hash = LuaInterop.lua_touserdata(m_state, i).GetInt(); - if(m_objectsMap.TryGetValue(l_hash, out var l_refObj)) - p_results.Add(l_refObj.m_object); - else - p_results.Add(null); - continue; - } - p_results.Add(null); - } - LuaInterop.lua_settop(m_state, l_top); + p_results.Add(ReadValue(i)); + if(p_results.Count > 0) + LuaInterop.lua_pop(m_state, p_results.Count); } } else @@ -265,16 +238,46 @@ static int ObjectsGC(IntPtr p_state) return 0; } - // Extended pushes + // Extended reads/pushes + public object ReadValue(int p_index) + { + object l_result = null; + if(LuaInterop.lua_isinteger(m_state, p_index) == 1) + l_result = LuaInterop.lua_tointeger(m_state, p_index); + else + { + switch(LuaInterop.lua_type(m_state, p_index)) + { + case LuaInterop.LUA_TBOOLEAN: + l_result = (LuaInterop.lua_toboolean(m_state, p_index) == 1); + break; + case LuaInterop.LUA_TNUMBER: + l_result = LuaInterop.lua_tonumber(m_state, p_index); + break; + case LuaInterop.LUA_TSTRING: + l_result = LuaInterop.lua_tostring(m_state, p_index); + break; + case LuaInterop.LUA_TUSERDATA: + { + long l_hash = LuaInterop.lua_touserdata(m_state, p_index).GetInt(); + if(m_objectsMap.TryGetValue(l_hash, out var l_refObj)) + l_result = l_refObj.m_object; + } + break; + } + } + return l_result; + } + public void PushValue(object p_value) { + // Always pushes something if(p_value == null) { PushNil(); return; } - // Always pushes something switch(Type.GetTypeCode(p_value.GetType())) { case TypeCode.Boolean: @@ -370,14 +373,15 @@ static int Log(IntPtr p_state) } // Classes - internal void RegisterClass(Type p_type, + internal void RegisterClass( + Type p_type, LuaInterop.lua_CFunction p_ctor, List<(string, (LuaInterop.lua_CFunction, LuaInterop.lua_CFunction))> p_staticProperties, List<(string, LuaInterop.lua_CFunction)> p_staticMethods, List<(string, LuaInterop.lua_CFunction)> p_metaMethods, List<(string, (LuaInterop.lua_CFunction, LuaInterop.lua_CFunction))> p_instanceProperties, List<(string, LuaInterop.lua_CFunction)> p_instanceMethods - ) + ) { // Static definition LuaInterop.lua_newtable(m_state); // {} diff --git a/CVRLua/LuaHandler.cs b/CVRLua/LuaHandler.cs index bcabb2c..0a39091 100644 --- a/CVRLua/LuaHandler.cs +++ b/CVRLua/LuaHandler.cs @@ -144,7 +144,7 @@ public void CallEvent(ScriptEvent p_event, params object[] p_args) public void CallEvent(ScriptEvent p_event, List p_result, params object[] p_args) { if(m_eventFunctions.TryGetValue(p_event, out int l_ref)) - m_vm.CallFunctionWithResults(l_ref, p_result, p_args); + m_vm.CallFunction(l_ref, p_result, p_args); } public void SetGlobalVariable(string p_name, object p_val) => m_vm.SetGlobalVariable(p_name, p_val);