lua-users home
lua-l archive

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

2011/6/24 Mike Pall <>:
> Benoit Germain wrote:
>> So back to square one: When running Lanes under LuaJIT, how can I
>> differentiate between a bytecode function and the other functions
>> using the C API besides guessing from what the debug infos tell me?
> If lua_dump() returns 1, then it's not a plain Lua function.
> --Mike

So now, in theory I have 3 types of closures that can be copied from
one state to another:
- pure Lua: the function proto is dumped out of the source state with
lua_dump(), then loaded in the target state with luaL_loadbuffer, and
the upvalues are transferred.
- LuaJIT fast: the source function is converted to a string with
tostring(), the entry is searched in a database stored in the target
state's registry, and the upvalues are assigned the same way as above.
- C functions: the C pointer is retrieved, the upvalues are pushed in
the target state, then the closure is created with lua_pushcclosure().

For the database, what I am doing now is this:
Right after the state for a new lane has been created and its base
libraries loaded, I perform a recursive search for non-Lua functions
inside _G. I store string/func pairs, where the string is generated by
tostring(func). This has the benefit of avoiding to hardcode the list
of functions I want to store in the database. The drawback is that I
need tostring() to be loaded in all lua_States, which is not
necessarily the case (it is perfectly valid to create a lane with an
empty lua state).

As you suggested, I can tell a Lua function by trying to dump it. With
a dumper callback that just returns some special value, any function
that I attempt to dump that causes lua_dump() to return that value
must therefore be a Lua function.

This seems to be working well enough that the few Lanes self-tests I
checked are now running fine with LuaJIT, which is good news :-).

Now, I don't want to "remap" C functions that way, but only
LuaJIT-fast functions. However, I can't reliably tell the difference
between a C function and a LuaJIT-fast function.
I have tried with lua_iscfunction(), but it seems to return true on
LuaJIT-fast functions as well. I've then tried with lua_tocfunction(),
because I noticed earlier that it seemed to return NULL for
LuaJIT-fast functions. Unfortunately, this doesn't seem to be the case
100% of the time, since for example I get NULL for coroutine.yield,
and a non-NULL pointer for coroutine.wrap.

So, is there some simple way for me to tell the difference between the
two function types besides checking what tostring(f) will give me? It
happens that having lua_tocfunction() returning a special unique
pointer for each fast function would serve the purpose just fine, as
well as removing a dependency I have on tostring().