Skip to content

Commit e461644

Browse files
committed
Working on stability + luajit debugging
1 parent 4bb00b3 commit e461644

File tree

4 files changed

+155
-12
lines changed

4 files changed

+155
-12
lines changed

Externals/LuaJIT-proj/LuaJIT.vcxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<ClCompile>
3030
<AdditionalIncludeDirectories>$(ProjectDir)intermediate\$(PlatformShortName);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
3131
<PreprocessorDefinitions>LUA_BUILD_AS_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
32-
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">LUAJIT_ENABLE_GC64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
32+
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">LUAJIT_ENABLE_GC64;LUA_USE_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
3333
<PrecompiledHeader>NotUsing</PrecompiledHeader>
3434
<TreatWarningAsError>false</TreatWarningAsError>
3535
</ClCompile>

src/xrAnimation/OzzKinematics.cpp

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,15 @@ bool OzzKinematics::LoadOzzAnimationsFromFile(const xr_string& relative_path)
870870

871871
payload.resize(static_cast<size_t>(length));
872872
if (!payload.empty())
873-
file.Read(payload.data(), payload.size());
873+
{
874+
const size_t bytes_read = file.Read(payload.data(), payload.size());
875+
if (bytes_read != payload.size())
876+
{
877+
Msg("[ozz] failed to read %zu bytes from '%s' (got %zu)", payload.size(), absolute.string().c_str(),
878+
bytes_read);
879+
return false;
880+
}
881+
}
874882
}
875883
else
876884
{
@@ -882,7 +890,15 @@ bool OzzKinematics::LoadOzzAnimationsFromFile(const xr_string& relative_path)
882890
const size_t length = static_cast<size_t>(reader->length());
883891
payload.resize(length);
884892
if (length > 0)
893+
{
894+
if (!reader->pointer())
895+
{
896+
Msg("[ozz] reader for '%s' returned null pointer", relative_path.c_str());
897+
FS.r_close(reader);
898+
return false;
899+
}
885900
std::memcpy(payload.data(), reader->pointer(), length);
901+
}
886902
FS.r_close(reader);
887903
}
888904

@@ -1964,9 +1980,64 @@ void OzzKinematics::LL_BuldBoneMatrixDequatize(const CBoneData* bd, u8 channel_m
19641980
}
19651981
}
19661982

1967-
void OzzKinematics::LL_BoneMatrixBuild(CBoneInstance& /*bi*/, const Fmatrix* /*parent*/, const SKeyTable& /*keys*/)
1983+
void OzzKinematics::LL_BoneMatrixBuild(CBoneInstance& bi, const Fmatrix* parent, const SKeyTable& keys)
19681984
{
1969-
NotImplemented(__FUNCTION__);
1985+
CKey channel_keys[MAX_CHANNELS];
1986+
Render::animation::channel_def channel_defs[MAX_CHANNELS];
1987+
u16 channel_count = 0;
1988+
1989+
for (u16 channel = 0; channel < MAX_CHANNELS; ++channel)
1990+
{
1991+
if (channel != 0 && keys.chanel_blend_conts[channel] == 0)
1992+
continue;
1993+
1994+
Render::animation::channel_def def{};
1995+
def.rule = channelRules[channel];
1996+
def.factor = channelFactors[channel];
1997+
1998+
channel_defs[channel_count] = def;
1999+
xray::render::RENDER_NAMESPACE::process_single_channel(channel_keys[channel_count], def, keys.keys[channel], keys.blends[channel],
2000+
keys.chanel_blend_conts[channel]);
2001+
++channel_count;
2002+
}
2003+
2004+
if (channel_count == 0)
2005+
{
2006+
if (parent)
2007+
bi.mTransform = *parent;
2008+
else
2009+
bi.mTransform.identity();
2010+
return;
2011+
}
2012+
2013+
CKey mixed_key;
2014+
xray::render::RENDER_NAMESPACE::MixChannels(mixed_key, channel_keys, channel_defs, channel_count);
2015+
2016+
Fmatrix local_matrix;
2017+
local_matrix.mk_xform(mixed_key.Q, mixed_key.T);
2018+
2019+
if (parent)
2020+
bi.mTransform.mul_43(*parent, local_matrix);
2021+
else
2022+
bi.mTransform = local_matrix;
2023+
2024+
#ifdef DEBUG
2025+
#ifndef _EDITOR
2026+
if (!xray::render::RENDER_NAMESPACE::check_scale(local_matrix))
2027+
{
2028+
VERIFY(xray::render::RENDER_NAMESPACE::check_scale(bi.mTransform));
2029+
}
2030+
VERIFY(_valid(bi.mTransform));
2031+
2032+
Fbox dbg_box;
2033+
constexpr float kBoxExtent = 100000.f;
2034+
dbg_box.set(-kBoxExtent, -kBoxExtent, -kBoxExtent, kBoxExtent, kBoxExtent, kBoxExtent);
2035+
VERIFY2(dbg_box.contains(bi.mTransform.c),
2036+
make_string("[OzzKinematics] bone transform out of bounds: (%.3f, %.3f, %.3f)", bi.mTransform.c.x,
2037+
bi.mTransform.c.y, bi.mTransform.c.z)
2038+
.c_str());
2039+
#endif
2040+
#endif
19702041
}
19712042

19722043
IBlendDestroyCallback* OzzKinematics::GetBlendDestroyCallback()

src/xrScriptEngine/script_engine.cpp

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <luabind/class_info.hpp>
3131

3232
#include <stdarg.h>
33+
#include <limits>
3334

3435
Flags32 g_LuaDebug;
3536
int g_LuaDumpDepth = 0;
@@ -140,8 +141,11 @@ void CScriptEngine::reinit()
140141
file_header = file_header_new;
141142
else
142143
file_header = file_header_old;
143-
scriptBufferSize = 1024 * 1024;
144+
constexpr size_t kInitialScriptBufferSize = 1024 * 1024 + 1;
145+
scriptBufferSize = kInitialScriptBufferSize;
144146
scriptBuffer = xr_alloc<char>(scriptBufferSize);
147+
if (scriptBuffer)
148+
scriptBuffer[0] = '\0';
145149

146150
if (m_profiler)
147151
m_profiler->OnReinit(m_virtual_machine);
@@ -313,6 +317,9 @@ bool CScriptEngine::parse_namespace(pcstr caNamespaceName, pstr b, size_t b_size
313317
bool CScriptEngine::load_buffer(
314318
lua_State* L, LPCSTR caBuffer, size_t tSize, LPCSTR caScriptName, LPCSTR caNameSpaceName)
315319
{
320+
m_lastLoadedChunk = caScriptName ? caScriptName : "<unnamed chunk>";
321+
m_lastLoadedNamespace = caNameSpaceName ? caNameSpaceName : GlobalNamespace;
322+
316323
int l_iErrorCode;
317324
if (caNameSpaceName && xr_strcmp(GlobalNamespace, caNameSpaceName))
318325
{
@@ -323,14 +330,35 @@ lua_State* L, LPCSTR caBuffer, size_t tSize, LPCSTR caScriptName, LPCSTR caNameS
323330
xr_sprintf(insert, header, caNameSpaceName, a, b);
324331
const size_t str_len = xr_strlen(insert);
325332
const size_t total_size = str_len + tSize;
326-
if (total_size >= scriptBufferSize)
333+
if (total_size < str_len)
334+
{
335+
script_log(LuaMessageType::Error, "script namespace header overflow for %s", caScriptName);
336+
on_error(L);
337+
return false;
338+
}
339+
if (total_size > std::numeric_limits<size_t>::max() - 1)
340+
{
341+
script_log(LuaMessageType::Error, "script buffer size overflow for %s", caScriptName);
342+
on_error(L);
343+
return false;
344+
}
345+
const size_t required_size = total_size + 1; // extra byte for sentinel '\0'
346+
if (required_size > scriptBufferSize)
327347
{
328-
scriptBufferSize = total_size;
329-
scriptBuffer = (char*)xr_realloc(scriptBuffer, scriptBufferSize);
348+
scriptBufferSize = required_size;
349+
scriptBuffer = static_cast<char*>(xr_realloc(scriptBuffer, scriptBufferSize));
350+
if (!scriptBuffer)
351+
{
352+
script_log(LuaMessageType::Error, "out of memory while resizing script buffer for %s", caScriptName);
353+
on_error(L);
354+
return false;
355+
}
330356
}
331-
xr_strcpy(scriptBuffer, total_size, insert);
332-
CopyMemory(scriptBuffer + str_len, caBuffer, tSize);
333-
l_iErrorCode = luaL_loadbuffer(L, scriptBuffer, tSize + str_len, caScriptName);
357+
xr_strcpy(scriptBuffer, scriptBufferSize, insert);
358+
if (tSize > 0)
359+
CopyMemory(scriptBuffer + str_len, caBuffer, tSize);
360+
scriptBuffer[total_size] = '\0';
361+
l_iErrorCode = luaL_loadbuffer(L, scriptBuffer, total_size, caScriptName);
334362
}
335363
else
336364
l_iErrorCode = luaL_loadbuffer(L, caBuffer, tSize, caScriptName);
@@ -370,6 +398,7 @@ bool CScriptEngine::do_file(LPCSTR caScriptName, LPCSTR caNameSpaceName)
370398
if (debugger())
371399
errFuncId = debugger()->PrepareLua(lua());
372400
#endif
401+
m_lastExecutingChunk = caScriptName ? caScriptName : "<unnamed chunk>";
373402
if (0) //.
374403
{
375404
for (int i = 0; lua_type(lua(), -i - 1); i++)
@@ -639,6 +668,9 @@ CScriptEngine::CScriptEngine(bool is_editor, bool is_with_profiler)
639668
m_reload_modules = false;
640669
m_last_no_file_length = 0;
641670
*m_last_no_file = 0;
671+
m_lastLoadedChunk.clear();
672+
m_lastLoadedNamespace = GlobalNamespace;
673+
m_lastExecutingChunk.clear();
642674
#ifdef USE_DEBUGGER
643675
#ifndef USE_LUA_STUDIO
644676
static_assert(false, "Do not define USE_LUA_STUDIO macro without USE_DEBUGGER macro");
@@ -1174,3 +1206,37 @@ bool CScriptEngine::is_editor()
11741206
{
11751207
return m_is_editor;
11761208
}
1209+
1210+
void CScriptEngine::OnLuaAssertion(lua_State* state, pcstr file, int line, pcstr func, pcstr message)
1211+
{
1212+
const pcstr loadedChunk = m_lastLoadedChunk.empty() ? "<none>" : m_lastLoadedChunk.c_str();
1213+
const pcstr namespaceName = m_lastLoadedNamespace.empty() ? GlobalNamespace : m_lastLoadedNamespace.c_str();
1214+
const pcstr executingChunk = m_lastExecutingChunk.empty() ? loadedChunk : m_lastExecutingChunk.c_str();
1215+
1216+
Msg("! [LuaJIT] ASSERT %s:%d (%s): %s", file ? file : "<unknown>", line,
1217+
func ? func : "<unknown>", (message && message[0]) ? message : "<no message>");
1218+
Msg("! [LuaJIT] last loaded chunk: %s (namespace: %s)", loadedChunk, namespaceName);
1219+
Msg("! [LuaJIT] last executing chunk: %s", executingChunk);
1220+
1221+
#ifdef DEBUG
1222+
const bool reenter = logReenterability;
1223+
logReenterability = true;
1224+
if (state)
1225+
print_stack(state);
1226+
logReenterability = reenter;
1227+
#else
1228+
(void)state;
1229+
#endif
1230+
}
1231+
1232+
extern "C" XRSCRIPTENGINE_API void xr_LuaAssertionHandler(lua_State* state, const char* file, int line, const char* func, const char* message)
1233+
{
1234+
if (!state)
1235+
return;
1236+
1237+
CScriptEngine* engine = CScriptEngine::GetInstance(state);
1238+
if (!engine)
1239+
return;
1240+
1241+
engine->OnLuaAssertion(state, file, line, func, message);
1242+
}

src/xrScriptEngine/script_engine.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#pragma once
1010

1111
#include "xrCommon/xr_unordered_map.h"
12+
#include "xrCommon/xr_string.h"
1213

1314
#include "xrCore/Containers/AssociativeVector.hpp"
1415
#include "xrCore/Threading/Lock.hpp"
@@ -77,6 +78,9 @@ class XRSCRIPTENGINE_API CScriptEngine
7778
char* scriptBuffer = nullptr;
7879
size_t scriptBufferSize = 0;
7980
bool m_is_editor;
81+
xr_string m_lastLoadedChunk;
82+
xr_string m_lastLoadedNamespace;
83+
xr_string m_lastExecutingChunk;
8084

8185
protected:
8286
CScriptProcessStorage m_script_processes;
@@ -87,9 +91,10 @@ class XRSCRIPTENGINE_API CScriptEngine
8791
#ifdef USE_DEBUGGER
8892
CScriptDebugger* m_scriptDebugger{};
8993
#endif
94+
public:
95+
static CScriptEngine* GetInstance(lua_State* state);
9096

9197
private:
92-
static CScriptEngine* GetInstance(lua_State* state);
9398
static bool RegisterState(lua_State* state, CScriptEngine* scriptEngine);
9499
static bool UnregisterState(lua_State* state);
95100
bool no_file_exists(pcstr file_name, size_t string_length);
@@ -198,6 +203,7 @@ class XRSCRIPTENGINE_API CScriptEngine
198203

199204
public:
200205
static void on_error(lua_State* state);
206+
void OnLuaAssertion(lua_State* state, pcstr file, int line, pcstr func, pcstr message);
201207

202208
void flush_log();
203209
void print_stack(lua_State* L = nullptr);

0 commit comments

Comments
 (0)