lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

Hello list
As said, I am back to lua. Testing luapi, I noted that just after
initialization, the stack top was
left at 8 ( my test host program shows the stack top after every
operation ).
Intrigued, a tried a simple thing: taking the stack top just after state
initialization, and settopping
it after the whole initialization function. This worked: again the stack top
currently is zero.
But ...
As said in my previous mail, I am playing with userdata. A test library on
initialization creates
6 global userdata objects.
Looking at the global table, I suddenly realized that one of my userdata
globals had a type of
table, and browsing its contents, it brings up all the coroutine members ...
in other words,
the coroutine table transmuted to my userdata. Checking the code, I saw that
the ´transmuted´
userdata was the first one in creation order. I added ( inserted ) one more,
and this time the
transmuted was the new first.
Because my library is invoked just after lua libraries initialization, I
moved the call to lua_settop to
just after the lua libraries ... and all went back to expected: the
coroutine table was there, and my
first userdata appeared as such.
snip of code follows
lua_State * luapi_open( lua_State ** L, luapi_Alert_Stub hostalert )
   int          sp;
   int          i;
   luapials_t * c;

   if ( L == NULL )
      L = & luapi_Lua; // default context 3.2 compatibility

   if ( * L != NULL )  // prevent double opening
      return * L;

   * L = lua_open( );

   if ( * L == NULL )
      return * L;

   sp = lua_gettop( * L );  // was added after stack top = 8

   lua_atpanic( * L, luapi_panic );

   lua_baselibopen( * L );
   lua_iolibopen( * L );
   lua_strlibopen( * L );
   lua_tablibopen( * L );
   lua_mathlibopen( * L );
   lua_dblibopen( * L );

   lua_settop( * L, sp );  // here was moved the settop call,
                                    // this stopped the userdata clobbering

   lua_register( * L, "_ALERT", luapi_alertfun );

   if ( hostalert ) {      // (1)
      luapi_setselferrstub( * L, hostalert );
      if ( ! host_alert_stub )
         host_alert_stub = hostalert;

   for ( i = 0, c = alstart; i < LUAPI_ALS; i ++, c ++ ) {  // (2)
      if ( c->lf ) {
         (* c->lf) ( * L, c->ln );

// lua_settop( * L, sp );  here was the original call to get rid of stack
top = 8

   return * L;

For the sake of completeness, I leave the code as is, but some explanations
are necessary
(1) this fragment records a host routine which does something with the error
messages. The
idea is that different contexts may have different needs regarding the
´destination´ of the messages.
The function setselferrstub creates one table in the registry, with at least
one member wich points
to the ´display´ function for this context.
Nevetheless, it is convenient to have a ´global´ display function at least
because panic can not
invoke any more of the context, but the user can be aware of the reason for
an unexpected stop run.

(2) One of my ideas: the application can ´record´ some libraries that must
be present in every
context it could create. So, before any lua interaction, it can populate
this table. After that, at
context opening, every library will be informed about. Such is the mechanism
I am using to
start the test userdata library.

Am I missing something  ?
The source code is the last release ( April 11 )