lua-users home
lua-l archive

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


Ben Sunshine-Hill wrote:
...
\begin{hack}
If you know that a particular object is being stored in a userdata,
you CAN refer to it as a userdata. All it takes is some pointer
arithmetic.

Ya see, a userdata, as allocated on the heap, consists of a struct
Udata (well, actually a union Udata, but only for alignment purposes;
treat it as a struct) followed by an arbitrary amount of data. The
struct portion is a GCable object, which can be set into a stack
position with setuvalue (a macro defined in lobject.h). This function,
therefore, should work, though it's untested. Written based on the
5.0.2 source. (You will, of course, need to modify the include to
correctly penetrate into the internals of Lua; lobject.h is not a
public header.)

#include <lobject.h>
void pushexistinguserdata(lua_State *L, void *ud)
{
  lua_lock(L);
  u = luaS_newudata(L, size);
  setuvalue(L->top, ((Udata*)ud)-1);
  api_incr_top(L);
  lua_unlock(L);
}

If you call this with a pointer that is not actually a pointer to a
preexisting userdata, horrible horrible things will happen within the
GC. Use with caution and revulsion.

Yes, this is just about the code I came up with (without the erroneous newudata), by patterning after lua_newuserdata(). I am not very happy about subverting Lua like this either, except that I really need the performance boost and I REALLY, REALLY promise that the pointer will always be good :-)

This could be made at least conceptually type safe by returning the userdata pointer from lua_newuserdata() as an opaque pointer rather than a void*:

    typedef struct lua_UserData lua_UserData;
    lua_UserData* lua_newuserdata(lua_State* L, size_t size);
    void          lua_pushuserdata(lua_State* L, lua_UserData* U);
    lua_UserData* lua_touserdata(lua_State* L);

For now I will hack it in!!!

Thanks...

--
chris marrin                ,""$,
chris@marrin.com          b`    $                             ,,.
                        mP     b'                            , 1$'
        ,.`           ,b`    ,`                              :$$'
     ,|`             mP    ,`                                       ,mm
   ,b"              b"   ,`            ,mm      m$$    ,m         ,`P$$
  m$`             ,b`  .` ,mm        ,'|$P   ,|"1$`  ,b$P       ,`  :$1
 b$`             ,$: :,`` |$$      ,`   $$` ,|` ,$$,,`"$$     .`    :$|
b$|            _m$`,:`    :$1   ,`     ,$Pm|`    `    :$$,..;"'     |$:
P$b,      _;b$$b$1"       |$$ ,`      ,$$"             ``'          $$
 ```"```'"    `"`         `""`        ""`                          ,P`
"As a general rule,don't solve puzzles that open portals to Hell"'