| 1522 | } |
| 1523 | |
| 1524 | static int PCallInternal(lua_State* L, int nargs, int nresult, int in_error_handler) { |
| 1525 | lua_pushcfunction(L, BacktraceErrorHandler); |
| 1526 | int err_index = lua_gettop(L) - nargs - 1; |
| 1527 | lua_insert(L, err_index); |
| 1528 | int result = lua_pcall(L, nargs, nresult, err_index); |
| 1529 | lua_remove(L, err_index); |
| 1530 | if (result == LUA_ERRMEM) { |
| 1531 | lua_pop(L, 1); // Pop BacktraceErrorHandler since it will not be called on OOM |
| 1532 | dmLogError("Lua memory allocation error."); |
| 1533 | } else if (result != 0) { |
| 1534 | // extract the individual fields for printing and passing |
| 1535 | lua_getfield(L, -1, "error"); |
| 1536 | lua_getfield(L, -2, "traceback"); |
| 1537 | // if handling error that happened during the error handling, print it and clean up and exit |
| 1538 | if (in_error_handler) { |
| 1539 | const char* error_msg = lua_tostring(L, -2); |
| 1540 | const char* traceback_msg = lua_tostring(L, -1); |
| 1541 | dmLogError("In error handler: %s%s", |
| 1542 | error_msg ? error_msg : "(error value could not be converted to string)", |
| 1543 | traceback_msg ? traceback_msg : "(traceback unavailable)"); |
| 1544 | lua_pop(L, 3); |
| 1545 | return result; |
| 1546 | } |
| 1547 | // print before calling the error handler |
| 1548 | const char* error_msg = lua_tostring(L, -2); |
| 1549 | const char* traceback_msg = lua_tostring(L, -1); |
| 1550 | dmLogError("%s\n%s", |
| 1551 | error_msg ? error_msg : "(error value could not be converted to string)", |
| 1552 | traceback_msg ? traceback_msg : "(traceback unavailable)"); |
| 1553 | lua_getfield(L, LUA_GLOBALSINDEX, "debug"); |
| 1554 | if (lua_istable(L, -1)) { |
| 1555 | lua_pushliteral(L, SCRIPT_ERROR_HANDLER_VAR); |
| 1556 | lua_rawget(L, -2); |
| 1557 | if (lua_isfunction(L, -1)) { |
| 1558 | lua_pushlstring(L, "lua", 3); // 1st arg: source = 'lua' |
| 1559 | lua_pushvalue(L, -5); // 2nd arg: error |
| 1560 | lua_pushvalue(L, -5); // 3rd arg: traceback |
| 1561 | PCallInternal(L, 3, 0, 1); |
| 1562 | } else { |
| 1563 | if (!lua_isnil(L, -1)) { |
| 1564 | dmLogError("Registered error handler is not a function"); |
| 1565 | } |
| 1566 | lua_pop(L, 1); |
| 1567 | } |
| 1568 | } |
| 1569 | lua_pop(L, 4); // debug value, traceback, error, table |
| 1570 | } |
| 1571 | return result; |
| 1572 | } |
| 1573 | |
| 1574 | int PCall(lua_State* L, int nargs, int nresult) { |
| 1575 | return PCallInternal(L, nargs, nresult, 0); |
no test coverage detected