lua_error() and C++

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

lua_error() and C++

David Morris-Oliveros
From my understanding, lua_error() does a longjump. How nicely (if at all) does this play with C++'s unwinding? For example:

int check(lua_State* L)
{
   StateMaintainer sm(GetGlobalState());

   sm.ModifyState(State::FunkyModification);

   if (lua_gettop(L) != 2)
   {
      lua_pushstring (L, "Wrong number of args!");
      lua_error(L);
   }

   // something

   return 0;
}

At the end of this function, C++ will call StateMaintainer's destructor on sm. But if there's an error, and lua_error() is called, then, is it called at all? Or is it silently ignored?

--
// David Morris-Oliveros
// Camera Coder
// Team Bondi


------------------------------------------------------------------------
Contact:
Team Bondi Pty Ltd
Level 2, 608 Harris Street
Ultimo, NSW 2007
Australia
Tel: +61 (0)2 8218 1500
Fax: +61 (0)2 8218 1507
Web: http://www.teambondi.com
------------------------------------------------------------------------
This email may contain confidential information.  If you are not
the intended recipient, you may not copy or deliver this message to
anyone. In such case, you should destroy this message and kindly
notify the sender by reply email. Opinions, conclusions and other
information in this message that do not relate to the official business
of our firm shall be understood as neither given nor endorsed by it.
------------------------------------------------------------------------


Reply | Threaded
Open this post in threaded view
|

Re: lua_error() and C++

D Burgess-4
Hello 

>  How nicely (if at
> all) does this play with C++'s unwinding? For example:
>

Depends on your compiler. I can tell you what happens with MS VC6.
I suspect similar issues with other compilers. This has been previously
discussed on this list.

You need to compile your C++ with /EHsc-, this generates code that
tells C++ that C can throw exceptions. Without this C++ code assumes
that C will never throw an exception.

If you are going to be using Lua under a lot of C++ for a small 
performance hit you can replace the Lua longjmp code with 
try/catch and compile one Lua module as C++. This for shaky
compilers puts all of the exception handling under one exception
management mechanism.

I would be interested to know what is the current state of play with gcc.

For MS VC6 I did the following ( I can send you the complete patch
if you like)

1) copied ldo.c to ldo.cpp
2) In ldo.cpp added

class lua_exception {
  int status;
public:
  lua_exception(int status_) : status(status_) { };
  int get_status() { return status; }
};


3) Changed

void luaD_throw (lua_State *L, int errcode) {
  if (L->errorJmp) {
    throw lua_exception(errcode);
  }
  else {
    G(L)->panic(L);
    exit(EXIT_FAILURE);
  }
}

int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
  struct lua_longjmp lj;
  lj.status = 0;
  lj.previous = L->errorJmp;  /* chain new error handler */
  L->errorJmp = &lj;
  try {
    (*f)(L, ud);
  }
  catch (lua_exception &e) {  /* an error occurred: restore the state */
    lj.status = e.get_status();
  }
  catch (...) {
    throw;
  }
  L->errorJmp = lj.previous;  /* restore old error handler */
  return lj.status;
}

4) Compiled everything with /GX /EHsc-
This has been working ok for me.

Finally Lua5.1 work6 has build time options for using try/catch rather
than longjmp. The important point is that the exception handling is
localized to ldo.c in two functions so that it is rather easy to install
whatever exception handling mechanism that you prefer.

DB


Reply | Threaded
Open this post in threaded view
|

Re: lua_error() and C++

Edwin Eyan Moragas-2
let me just throw in my praises.
amazing! David, i am in love with your skill.
(Just had my dose of Samurai 7. sorry, can't
help it).

-- 
salud,
eyan


On 8/3/05, David Burgess <[hidden email]> wrote:
> Hello
> 
> >  How nicely (if at
> > all) does this play with C++'s unwinding? For example:
> >
> 
> Depends on your compiler. I can tell you what happens with MS VC6.
> I suspect similar issues with other compilers. This has been previously
> discussed on this list.
> 
> You need to compile your C++ with /EHsc-, this generates code that
> tells C++ that C can throw exceptions. Without this C++ code assumes
> that C will never throw an exception.
> 
> If you are going to be using Lua under a lot of C++ for a small
> performance hit you can replace the Lua longjmp code with
> try/catch and compile one Lua module as C++. This for shaky
> compilers puts all of the exception handling under one exception
> management mechanism.
> 
> I would be interested to know what is the current state of play with gcc.
> 
> For MS VC6 I did the following ( I can send you the complete patch
> if you like)
> 
> 1) copied ldo.c to ldo.cpp
> 2) In ldo.cpp added
> 
> class lua_exception {
>   int status;
> public:
>   lua_exception(int status_) : status(status_) { };
>   int get_status() { return status; }
> };
> 
> 
> 3) Changed
> 
> void luaD_throw (lua_State *L, int errcode) {
>   if (L->errorJmp) {
>     throw lua_exception(errcode);
>   }
>   else {
>     G(L)->panic(L);
>     exit(EXIT_FAILURE);
>   }
> }
> 
> int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
>   struct lua_longjmp lj;
>   lj.status = 0;
>   lj.previous = L->errorJmp;  /* chain new error handler */
>   L->errorJmp = &lj;
>   try {
>     (*f)(L, ud);
>   }
>   catch (lua_exception &e) {  /* an error occurred: restore the state */
>     lj.status = e.get_status();
>   }
>   catch (...) {
>     throw;
>   }
>   L->errorJmp = lj.previous;  /* restore old error handler */
>   return lj.status;
> }
> 
> 4) Compiled everything with /GX /EHsc-
> This has been working ok for me.
> 
> Finally Lua5.1 work6 has build time options for using try/catch rather
> than longjmp. The important point is that the exception handling is
> localized to ldo.c in two functions so that it is rather easy to install
> whatever exception handling mechanism that you prefer.
> 
> DB
>


Reply | Threaded
Open this post in threaded view
|

Re: lua_error() and C++

D Burgess-4
This mail I forward on behalf of Nikolas Bowe.
I edited it slightly.
Message Follows:


-------------------- 
regarding your patch to allow C++ exceptions:
 
I checked the docs and /GX is supposed to be equivilant to /EHsc. so
you only need to compile everything with /EHsc-
 
Also on visual studio 7.1 (aka .net 2003) you can right click on ldo.c
and change its properties to compile as C++. this saves you from
changing the name. matter of personal taste I guess.
 
You mentioned that you wondered what gcc did.
I tried a small C source file that I put try catch into and compiled
it with "g++" instead of "gcc" (3.4.1) and it worked perfectly.
I didnt try to throw the exception through code compiled as C (ie
compiled with "gcc") though.
so at the worst case the only thing you have to do is to compile
everything with "g++" instead of "gcc".
(this assumes of course that the information at
http://lua-users.org/wiki/BuildingLua is correct and lua builds
cleanly as C++)
Looking at the docs for gcc at
http://developer.apple.com/documentation/DeveloperTools/gcc-3.3/gcc/Code-Gen-Options.html
suggests that if you dont want to compile all of lua as C++ but still
want to use C++ exceptions thrown through the C code then you need to
compile ldo.c as C++ (ie with "g++"), but all the other C files you
can compile with "gcc" if you use the "-fexceptions " switch
 
Thanks again for your post.
 
Nikolas Bowe
Programmer
Infinite Interactive