Skip to content

Commit 39c2839

Browse files
committed
不能在c++函数(特别是包含try-catch的)里longjmp
1 parent 29d4c4c commit 39c2839

File tree

3 files changed

+55
-9
lines changed

3 files changed

+55
-9
lines changed

unity/native/papi-lua/include/CppObjectMapperLua.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ struct pesapi_callback_info__
2929
int ArgStart; // 0 or 1
3030
int RetNum;
3131
void* Data;
32+
int HasError; // deferred error flag, similar to xlua's csharp_function_wrap pattern
33+
int ErrorMsgIdx; // absolute stack index of the error message
3234
};
3335

3436
struct PesapiCallbackData

unity/native/papi-lua/source/CppObjectMapperLua.cpp

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,13 @@ namespace luaimpl
231231
static int PesapiFunctionCallback(lua_State* L)
232232
{
233233
PesapiCallbackData* FunctionInfo = reinterpret_cast<PesapiCallbackData*>(lua_touserdata(L, lua_upvalueindex(1)));
234-
pesapi_callback_info__ info{L, FunctionInfo->ArgStart, 0, FunctionInfo->Data};
234+
pesapi_callback_info__ info{L, FunctionInfo->ArgStart, 0, FunctionInfo->Data, 0, 0};
235235
FunctionInfo->Callback(&g_pesapi_ffi, reinterpret_cast<pesapi_callback_info>(&info));
236+
if (info.HasError)
237+
{
238+
lua_pushvalue(L, info.ErrorMsgIdx);
239+
return lua_error(L);
240+
}
236241
return 1;
237242
}
238243

@@ -558,8 +563,13 @@ namespace luaimpl
558563
int object_new(lua_State* L)
559564
{
560565
puerts::ScriptClassDefinition* class_definition = static_cast<puerts::ScriptClassDefinition*>(lua_touserdata(L, lua_upvalueindex(1)));
561-
pesapi_callback_info__ callback_info{L, 1, 0, class_definition->Data};
566+
pesapi_callback_info__ callback_info{L, 1, 0, class_definition->Data, 0, 0};
562567
CppObjectMapper::Get(L)->BindCppObject(L, class_definition, class_definition->Initialize(&g_pesapi_ffi, reinterpret_cast<pesapi_callback_info>(&callback_info)), false);
568+
if (callback_info.HasError)
569+
{
570+
lua_pushvalue(L, callback_info.ErrorMsgIdx);
571+
return lua_error(L);
572+
}
563573
return 1;
564574
}
565575

@@ -654,50 +664,80 @@ namespace luaimpl
654664
int property_getter_wrap(lua_State* L)
655665
{
656666
puerts::ScriptPropertyInfo* prop_info = (puerts::ScriptPropertyInfo*)lua_touserdata(L, lua_upvalueindex(1));
657-
pesapi_callback_info__ callback_info{L, 1, 0, prop_info->GetterData};
667+
pesapi_callback_info__ callback_info{L, 1, 0, prop_info->GetterData, 0, 0};
658668
prop_info->Getter(&g_pesapi_ffi, reinterpret_cast<pesapi_callback_info>(&callback_info));
669+
if (callback_info.HasError)
670+
{
671+
lua_pushvalue(L, callback_info.ErrorMsgIdx);
672+
return lua_error(L);
673+
}
659674
return callback_info.RetNum;
660675
}
661676

662677
static int property_setter_wrap(lua_State* L)
663678
{
664679
puerts::ScriptPropertyInfo* prop_info = (puerts::ScriptPropertyInfo*)lua_touserdata(L, lua_upvalueindex(1));
665-
pesapi_callback_info__ callback_info{L, 1, 0, prop_info->SetterData};
680+
pesapi_callback_info__ callback_info{L, 1, 0, prop_info->SetterData, 0, 0};
666681
prop_info->Setter(&g_pesapi_ffi, reinterpret_cast<pesapi_callback_info>(&callback_info));
682+
if (callback_info.HasError)
683+
{
684+
lua_pushvalue(L, callback_info.ErrorMsgIdx);
685+
return lua_error(L);
686+
}
667687
return callback_info.RetNum;
668688
}
669689

670690
static int variable_getter_wrap(lua_State* L)
671691
{
672692

673693
puerts::ScriptPropertyInfo* prop_info = (puerts::ScriptPropertyInfo*)lua_touserdata(L, lua_upvalueindex(1));
674-
pesapi_callback_info__ callback_info{L, 0, 0, prop_info->GetterData};
694+
pesapi_callback_info__ callback_info{L, 0, 0, prop_info->GetterData, 0, 0};
675695
prop_info->Getter(&g_pesapi_ffi, reinterpret_cast<pesapi_callback_info>(&callback_info));
696+
if (callback_info.HasError)
697+
{
698+
lua_pushvalue(L, callback_info.ErrorMsgIdx);
699+
return lua_error(L);
700+
}
676701
return callback_info.RetNum;
677702
}
678703

679704
static int variable_setter_wrap(lua_State* L)
680705
{
681706
puerts::ScriptPropertyInfo* prop_info = (puerts::ScriptPropertyInfo*)lua_touserdata(L, lua_upvalueindex(1));
682-
pesapi_callback_info__ callback_info{L, 0, 0, prop_info->SetterData};
707+
pesapi_callback_info__ callback_info{L, 0, 0, prop_info->SetterData, 0, 0};
683708
prop_info->Setter(&g_pesapi_ffi, reinterpret_cast<pesapi_callback_info>(&callback_info));
709+
if (callback_info.HasError)
710+
{
711+
lua_pushvalue(L, callback_info.ErrorMsgIdx);
712+
return lua_error(L);
713+
}
684714
return callback_info.RetNum;
685715
}
686716

687717
static int method_wrap(lua_State* L)
688718
{
689719
puerts::ScriptFunctionInfo* func_info = (puerts::ScriptFunctionInfo*)lua_touserdata(L, lua_upvalueindex(1));
690-
pesapi_callback_info__ callback_info{L, 1, 0, func_info->Data};
720+
pesapi_callback_info__ callback_info{L, 1, 0, func_info->Data, 0, 0};
691721
func_info->Callback(&g_pesapi_ffi, reinterpret_cast<pesapi_callback_info>(&callback_info));
722+
if (callback_info.HasError)
723+
{
724+
lua_pushvalue(L, callback_info.ErrorMsgIdx);
725+
return lua_error(L);
726+
}
692727
return callback_info.RetNum;
693728
}
694729

695730
static int function_wrap(lua_State* L)
696731
{
697732

698733
puerts::ScriptFunctionInfo* func_info = (puerts::ScriptFunctionInfo*)lua_touserdata(L, lua_upvalueindex(1));
699-
pesapi_callback_info__ callback_info{L, 0, 0, func_info->Data};
734+
pesapi_callback_info__ callback_info{L, 0, 0, func_info->Data, 0, 0};
700735
func_info->Callback(&g_pesapi_ffi, reinterpret_cast<pesapi_callback_info>(&callback_info));
736+
if (callback_info.HasError)
737+
{
738+
lua_pushvalue(L, callback_info.ErrorMsgIdx);
739+
return lua_error(L);
740+
}
701741
return callback_info.RetNum;
702742
}
703743

unity/native/papi-lua/source/PesapiLuaImpl.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,11 @@ void pesapi_add_return(pesapi_callback_info pinfo, pesapi_value value)
508508
void pesapi_throw_by_string(pesapi_callback_info pinfo, const char* msg)
509509
{
510510
auto info = reinterpret_cast<pesapi::luaimpl::pesapi_callback_info__*>(pinfo);
511-
luaL_error(info->L, "%s", msg);
511+
// Deferred error: do not call luaL_error directly here to avoid longjmp
512+
// across C++ try-catch blocks. The error will be raised after the callback returns.
513+
lua_pushstring(info->L, msg);
514+
info->HasError = 1;
515+
info->ErrorMsgIdx = lua_absindex(info->L, -1);
512516
}
513517

514518
struct pesapi_env_ref__

0 commit comments

Comments
 (0)