From 58762ff88c58058c37a3d967611b107f9317de08 Mon Sep 17 00:00:00 2001 From: skywhub Date: Mon, 8 Jul 2024 16:30:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=B9=E4=BA=8E=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E7=9A=84=E7=BB=99lua=E8=B0=83=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E7=BB=91=E5=AE=9A=E5=87=BD=E6=95=B0=EF=BC=8Cstruct?= =?UTF-8?q?=E5=80=BC=E6=88=96=E8=80=85=E5=BC=95=E7=94=A8=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E4=BC=A0=E9=80=92nil=E4=BC=9A=E7=9B=B4=E6=8E=A5=E5=AF=BC?= =?UTF-8?q?=E8=87=B4crash=EF=BC=8C=E5=AF=B9=E6=AD=A4=E6=83=85=E5=86=B5?= =?UTF-8?q?=E6=96=B0=E5=A2=9EGetArgsChecked=E6=8E=A5=E5=8F=A3=E7=94=A8?= =?UTF-8?q?=E4=BA=8E=E6=8E=A5=E6=94=B6=E5=8F=82=E6=95=B0=E6=97=B6=E5=81=9A?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E4=BB=A5lua=20error=E4=BB=A3=E6=9B=BF?= =?UTF-8?q?=E7=9B=B4=E6=8E=A5crash=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Plugins/UnLua/Source/UnLua/Public/UnLuaEx.inl | 16 +++- .../UnLua/Source/UnLua/Public/UnLuaLegacy.h | 78 ++++++++++++++++--- .../UnLua/Source/UnLua/Public/UnLuaTemplate.h | 30 +++++++ 3 files changed, 111 insertions(+), 13 deletions(-) diff --git a/Plugins/UnLua/Source/UnLua/Public/UnLuaEx.inl b/Plugins/UnLua/Source/UnLua/Public/UnLuaEx.inl index 1dc4e269..4fa14610 100644 --- a/Plugins/UnLua/Source/UnLua/Public/UnLuaEx.inl +++ b/Plugins/UnLua/Source/UnLua/Public/UnLuaEx.inl @@ -250,6 +250,14 @@ namespace UnLua return TTuple(UnLua::Get(L, Offset + N, TType())...); } + /** + * Get arguments from Lua stack, avoid nullptr access crash but throw lua error + */ + template + FORCEINLINE_DEBUGGABLE TTuple GetArgsChecked(lua_State *L, TIndices, uint32 Offset = 0) + { + return TTuple(UnLua::GetChecked(L, Offset + N, TType())...); + } /** * Generic closure to help invoke exported function @@ -367,7 +375,7 @@ namespace UnLua return 0; } - TTuple::Type...> Args = GetArgs::Type...>(L, typename TOneBasedIndices::Type(), 1); + TTuple::Type...> Args = GetArgsChecked::Type...>(L, typename TOneBasedIndices::Type(), 1); Construct(L, Args, typename TZeroBasedIndices::Type()); return 1; } @@ -444,7 +452,7 @@ namespace UnLua return 0; } - TTuple::Type...> Args = GetArgs::Type...>(L, typename TOneBasedIndices::Type()); + TTuple::Type...> Args = GetArgsChecked::Type...>(L, typename TOneBasedIndices::Type()); Construct(L, Args, typename TZeroBasedIndices::Type()); return 1; } @@ -527,7 +535,7 @@ namespace UnLua UE_LOG(LogUnLua, Warning, TEXT("Attempted to call %s with invalid arguments. %d expected but got %d."), *Name, Expected, Actual); return 0; } - TTuple::Type...> Args = GetArgs::Type...>(L, typename TOneBasedIndices::Type()); + TTuple::Type...> Args = GetArgsChecked::Type...>(L, typename TOneBasedIndices::Type()); return TInvokingHelper::Invoke(L, Func, Args, typename TZeroBasedIndices::Type()); } @@ -579,7 +587,7 @@ namespace UnLua UE_LOG(LogUnLua, Warning, TEXT("Attempted to call %s::%s with invalid arguments. %d expected but got %d."), *ClassName, *Name, Expected, Actual); return 0; } - TTuple::Type...> Args = GetArgs::Type...>(L, typename TOneBasedIndices::Type()); + TTuple::Type...> Args = GetArgsChecked::Type...>(L, typename TOneBasedIndices::Type()); if (Args.template Get<0>() == nullptr) { UE_LOG(LogUnLua, Error, TEXT("Attempted to call %s::%s with nullptr of 'this'."), *ClassName, *Name); diff --git a/Plugins/UnLua/Source/UnLua/Public/UnLuaLegacy.h b/Plugins/UnLua/Source/UnLua/Public/UnLuaLegacy.h index 418b7095..c1ca0e31 100644 --- a/Plugins/UnLua/Source/UnLua/Public/UnLuaLegacy.h +++ b/Plugins/UnLua/Source/UnLua/Public/UnLuaLegacy.h @@ -474,12 +474,25 @@ namespace UnLua /** * Get value from the stack. */ - template T Get(lua_State* L, int32 Index, TType); + template auto Get(lua_State *L, int32 Index, TType) + -> std::enable_if_t, TType>::value, T>; - template T* Get(lua_State* L, int32 Index, TType); + template auto Get(lua_State *L, int32 Index, TType) + -> std::enable_if_t, TType>::value, T>; - template T& Get(lua_State* L, int32 Index, TType); + template T* Get(lua_State *L, int32 Index, TType); + template T& Get(lua_State *L, int32 Index, TType); + + template auto GetChecked(lua_State *L, int32 Index, TType) + -> std::enable_if_t, TType>::value, T>; + + template auto GetChecked(lua_State *L, int32 Index, TType) + -> std::enable_if_t, TType>::value, T>; + + template T* GetChecked(lua_State *L, int32 Index, TType); + + template T& GetChecked(lua_State *L, int32 Index, TType); template TSubclassOf Get(lua_State* L, int32 Index, TType>); template TSubclassOf* Get(lua_State* L, int32 Index, TType*>); template TSubclassOf& Get(lua_State* L, int32 Index, TType&>); @@ -1007,9 +1020,11 @@ namespace UnLua return TPointerHelper::Type>::Push(L, &V); } - static T Get(lua_State* L, int32 Index) + static T Get(lua_State *L, int32 Index, bool bIfNeedCheck = false) { - T* V = (T*)UnLua::GetPointer(L, Index); + T *V = (T*)UnLua::GetPointer(L, Index); + if ( UNLIKELY(!V) && bIfNeedCheck ) + luaL_typeerror(L, lua_absindex(L, Index), TType::Type>::GetName()); return *V; } }; @@ -1027,6 +1042,11 @@ namespace UnLua { return (T)lua_tointeger(L, Index); } + + static T Get(lua_State *L, int32 Index, bool bIfNeedCheck = false) + { + return (T)lua_tointeger(L, Index); + } }; @@ -1068,24 +1088,64 @@ namespace UnLua * Get value from the stack. */ template - FORCEINLINE T Get(lua_State* L, int32 Index, TType) + FORCEINLINE auto Get(lua_State *L, int32 Index, TType) + -> std::enable_if_t, TType>::value, T> { return TGenericTypeHelper::Get(L, Index); } + template + FORCEINLINE auto Get(lua_State *L, int32 Index, TType Ty) + -> std::enable_if_t, TType>::value, T> + { + return TGenericTypeHelper::Get(L, Index, Ty.bIfNeedCheck); + } + template - FORCEINLINE T* Get(lua_State* L, int32 Index, TType) + FORCEINLINE T* Get(lua_State *L, int32 Index, TType) { return TPointerHelper::Get(L, Index); } template - FORCEINLINE T& Get(lua_State* L, int32 Index, TType) + FORCEINLINE T& Get(lua_State *L, int32 Index, TType) { - T* V = TPointerHelper::Get(L, Index); + T *V = TPointerHelper::Get(L, Index); return *V; } + template + FORCEINLINE auto GetChecked(lua_State *L, int32 Index, TType Ty) + -> std::enable_if_t, TType>::value, T> + { + // NOT Checkable type && in check context, using custom UnLua::Get + return Get(L, Index, Ty); + } + + template + FORCEINLINE auto GetChecked(lua_State *L, int32 Index, TType Ty) + -> std::enable_if_t, TType>::value, T> + { + // Checkable type && in check context, using custom UnLua::Get or TGenericTypeHelper::Get + Ty.EnableCheck(); + return Get(L, Index, Ty); + } + + template + FORCEINLINE T* GetChecked(lua_State *L, int32 Index, TType Ty) + { + return Get(L, Index, Ty); + } + + template + FORCEINLINE T& GetChecked(lua_State *L, int32 Index, TType) + { + T *V = TPointerHelper::Get(L, Index); + if ( UNLIKELY(!V) ) + luaL_typeerror(L, lua_absindex(L, Index), TType::Type>::GetName()); + return *V; + } + template FORCEINLINE TSubclassOf Get(lua_State* L, int32 Index, TType>) { diff --git a/Plugins/UnLua/Source/UnLua/Public/UnLuaTemplate.h b/Plugins/UnLua/Source/UnLua/Public/UnLuaTemplate.h index 38b51ec9..17c15614 100644 --- a/Plugins/UnLua/Source/UnLua/Public/UnLuaTemplate.h +++ b/Plugins/UnLua/Source/UnLua/Public/UnLuaTemplate.h @@ -343,3 +343,33 @@ DEFINE_TYPE(FText) DEFINE_SMART_POINTER(TSharedPtr) DEFINE_SMART_POINTER(TSharedRef) DEFINE_SMART_POINTER(TWeakPtr) + +/** + * Define container names + */ +template +struct UnLua::TType, false> +{ + static const char * GetName() + { + return "TArray<>"; + } +}; + +template +struct UnLua::TType, false> +{ + static const char * GetName() + { + return "TMap<>"; + } +}; + +template +struct UnLua::TType, false> +{ + static const char * GetName() + { + return "TSet<>"; + } +}; \ No newline at end of file