If do_work succeeds, we return the resulting int answer. If it fails, we'll communicate that failure to our caller.
| 109 | // If do_work succeeds, we return the resulting int answer. If it fails, we'll |
| 110 | // communicate that failure to our caller. |
| 111 | int call_lua( lua_State * L ) |
| 112 | { |
| 113 | return leaf::try_catch( |
| 114 | [&] |
| 115 | { |
| 116 | leaf::error_monitor cur_err; |
| 117 | |
| 118 | // Ask the Lua interpreter to call the global Lua function call_do_work. |
| 119 | lua_getfield( L, LUA_GLOBALSINDEX, "call_do_work" ); |
| 120 | if( int err = lua_pcall(L, 0, 1, 0) ) |
| 121 | { |
| 122 | std::string msg = lua_tostring(L, 1); |
| 123 | lua_pop(L,1); |
| 124 | |
| 125 | // We got a Lua error which may be the error we're reporting |
| 126 | // from do_work, or some other error. If it is another error, |
| 127 | // cur_err.assigned_error_id() will return a new leaf::error_id, |
| 128 | // otherwise we'll be working with the original error reported |
| 129 | // by a C++ exception out of do_work. |
| 130 | leaf::throw_exception( cur_err.assigned_error_id().load( e_lua_pcall_error{err}, e_lua_error_message{std::move(msg)} ) ); |
| 131 | } |
| 132 | else |
| 133 | { |
| 134 | // Success! Just return the int answer. |
| 135 | int answer = lua_tonumber(L, -1); |
| 136 | lua_pop(L, 1); |
| 137 | return answer; |
| 138 | } |
| 139 | }, |
| 140 | |
| 141 | []( e_lua_exception e ) -> int |
| 142 | { |
| 143 | // This is the exception communicated out of wrap_lua_CFunction. |
| 144 | std::rethrow_exception( e.value ); |
| 145 | } ); |
| 146 | } |
| 147 | |
| 148 | int main() |
| 149 | { |
no test coverage detected