Skip to main content
GameDev.net gamedev.net
🔒 Locked

Lua: Avoiding premature exitulation by errorJmp'ing

Started by Luth Jul 3, 2007 at 3:53 PM 1 replies 1.8k views
Original Post
Luth
Luth
I have a function where I register C++ classes as user data in lua, and I wanted to avoid registering the same thing more than once, so I added two lines to the beginning of my register code:
if (luaL_checkudata(L, lua_gettop(L), T::className))
	return;
So, if it succeeds and finds the userdata, return immediately. Else, go ahead with registration. However, when checkudata fails, it goes through: luaL_typerror luaL_argerror luaL_error lua_error luaG_errormsg luaD_throw and finally, since L->errorJmp == NULL, exit I've googled around and read docs for the past hour or so, but I haven't yet stumbled across an appropriate way of dealing with this situation so that it does something (anything) other than exit()'ing. Help? :)
Sneftel
Sneftel
luaL_checkudata returns void, and signals failure by throwing a C-style exception. If failing the check isn't an error, it's not a function you should use. Check the type directly.
Luth
Luth
Quote:
Original post by Sneftel
luaL_checkudata returns void, and signals failure by throwing a C-style exception. If failing the check isn't an error, it's not a function you should use. Check the type directly.


void luaD_throw (lua_State *L, int errcode) {  if (L->errorJmp) {    L->errorJmp->status = errcode;    LUAI_THROW(L, L->errorJmp);  }  else {    L->status = cast_byte(errcode);    if (G(L)->panic) {      resetstack(L, errcode);      lua_unlock(L);      G(L)->panic(L);    }    exit(EXIT_FAILURE);  }}


Throwing an error is perfectly fine, if it did it. When it eventually gets its way to luaD_throw (via the call stack above), L->errorJmp is NULL, so instead of throw()ing, it exit()s instead.

So, in following up on your suggestion, if I registered the class using:
lua_newtable(L);		int methods = lua_gettop(L);		luaL_newmetatable(L, T::className);		int metatable = lua_gettop(L);		// store method table in globals so that		// scripts can add functions written in Lua.		lua_pushvalue(L, methods);		set(L, LUA_GLOBALSINDEX, T::className);		// hide metatable from Lua getmetatable()		lua_pushvalue(L, methods);		set(L, metatable, "__metatable");... etc ...		lua_newtable(L);                // mt for method table		lua_pushcfunction(L, new_T);		lua_pushvalue(L, -1);           // dup new_T function		set(L, methods, "new");         // add new_T to method table		set(L, -3, "__call");           // mt.__call = new_T		lua_setmetatable(L, methods);		// fill method table with methods from class T		for (RegType *l = (RegType*)T::methods; l->name; l++) {			lua_pushstring(L, l->name);			lua_pushlightuserdata(L, (void*)l);			lua_pushcclosure(L, thunk, 1);			lua_settable(L, methods);		}

what would I replace my checkudata with to see if T::className has already been registered? Would this work:
lua_getglobal(L, T::className);if(lua_istable(L, -1)){	lua_remove(L, -1);	return;}


[Edited by - Luth on July 3, 2007 4:33:46 PM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.