lua-users home
lua-l archive

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




On Mon, Oct 6, 2014 at 7:50 PM, Thiago Padilha <tpadilha84@gmail.com> wrote:
Philipp

I imagined that the lua VM maintained a separate "virtual" call stack
for every lua chunk, not only coroutines. What you mean is that every
lua call frame(except for those in coroutines) is also a C call frame?
If so, I understand the problem.

Thanks for the explanation\
 
I don't think that is right. Not every lua call is a C call frame and C call frames may happen in any Lua thread. 

Because I'm dealing with threads in my current project, and because my knowledge is new and fragile, I'd like to practice by providing my understanding:

In a Lua program's execution, C frames and lua frames are mixed within the main Lua stack, as functions call other functions that are in either.

C --> (L  --> L --> L) --> C --> (L --> L) --> C ...

Each call into and out of Lua is a black box, if viewed from C and ignoring internal Lua implementation details.

When a coroutine is fired by the resume function, it appears as the final call in Lua's call stack, with the last entry being a pointer to the last executed position (yield or the first frame is made by calling the  main function if yield hasn't happened) in the resumed thread's call stack. More function calls, either in C or Lua, may happen, including additional calls to resume. Therefore there are potentially dozens of Lua threads, each possibly containing a C function call.

As the Lua program is creating these stack entries in each of the thread's stacks, as `resume` is used to jump to different sacks, additional calls into C functions may appear. 
From C, ignoring internal calls into the Lua API, these "thread switches" look like:

1: call C function
2: call lua_library_function
  <<hidden from view: dozens of Lua function calls and 3 calls to resume happen. Now we're on thread ??? >>
3: call C function
4: call lua_library
  <<a yield happens, which brings us back to some point around 2.5... we later return and...>>
5: call C_function ...

When the yield happens, Lua is able to preserve the stack (locals, upvalues, current line, etc) between the yield and the calling resume, but only if no C functions were added between the last resume and the next yield. This is because in C, there is no mechanism that can parrot what coroutines do, as you know and so Lua stops execution to prevent it.

In 5.2, you can pass a pointer to a C callback / continuation function and a context object into the 'k' calling variants (lua_pcallk/lua_callk/lua_yieldk). In cases where Lua finds these calls on the call stack, the original C functions are destroyed and in Lua, they are replaced with the context object and a new call to the continuation function, which then receives context object, (upvalues, locals from the main function and the return values from yield for lua_yieldk). My details on this (and all other) part(s) are probably wrong, however...


Anyway, I look forward to the corrections/clarifications/affirmations. All that I have achieved in life, I owe to being wrong....


-Andrew