lua-users home
lua-l archive

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


Graham Wakefield wrote:
Just a sanity check - should there be a problem making these calls within a coroutine (thread) resumed from C? When I try, I get no error but also nothing actually happens. A bit hard to show the code here since it is embedded in a complex C++ application, sorry, but even this:

f = loadstring("print('hello')")
print("f()", f, f())

results in:

f()    function: 0x1095f60

i.e., no 'hello' appears.

I can't reproduce that, but I'm not sure in what context you're doing
that. Perhaps you should try:

print ("f()", f, xpcall(f, debug.traceback))

The only error I can think of is that 'print' isn't in the function
environment of the compiled chunk.


The main thread lua state is created like this:

L = lua_newstate(Lua :: alloc, 0); if (L) {
        //lua_atpanic(L, Lua :: panic);
        luaL_openlibs(L);
    }

The main lua file is then loaded into a lua_State * L like this:

    if (luaL_loadfile (L, path))
    {
        printf("dofile error: %s", lua_tostring(L, -1));
        lua_pop(L, 1);
    }

Then resumed like this:

int result = lua_resume(L, lua_gettop(L) - 1); // in case I pushed some args to it

I don't think you can resume the master state, although I could be wrong.



Is this part of the whole yielding across a pcall problem (which I have to admit is still not clear, despite reading many manual entries and lua-list messages).

When Lua calls a CFunction (and pcall, like the other library functions,
is a CFunction), it actually calls it, using the native stack. If the
function subsequently calls lua_call (or anything similar), then
the Lua VM is entered recursively.

There's no problem longjmp'ing up the stack, but it's not possible to
restore the stack in order to resume execution. yield() implies the
possibility of resume()ing, and it can be done in many cases, because
Lua does not call itself recursively when a Lua function is called.
But yield only works if the target of the yield is in the same C
callframe as the yield(). Consequenlty, you can't yield() through a
CFunction, such as pcall, table.foreach, or string.gsub, and similarly
you cannot yield through a metamethod (except for __call, which is
handled differently.)