lua-users home
lua-l archive

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


> From: Roberto Ierusalimschy [mailto:roberto@inf.puc-rio.br]
> Sent: Monday, July 07, 2003 6:10 AM
> To: Lua list
> Subject: Re: Assert in VM
> 
> > What does it mean when this assertion fails in the VM? (I chopped it
up
> > for clarity)
> >
> >           lua_assert(ci->u.l.pc == &pc);
> 
> Probably that your Lua stack is out of synch with your C stack.


I believe the implications of this are very bad (and thanks to Rici for
help here). This basically means that the call stack must be the same
every time you call through C to Lua. 

      case OP_CALL:
      case OP_TAILCALL: {
		....
        firstResult = luaD_precall(L, ra);
        if (firstResult) {
          if (firstResult > L->top) {  /* yield? */
            lua_assert(L->ci->state == (CI_C | CI_YIELD));
            (L->ci - 1)->u.l.savedpc = pc;
            (L->ci - 1)->state = CI_SAVEDPC;
            return NULL;
          }
		....

since:

	  const Instruction *pc;
	 callentry:  /* entry point when calling new functions */
	  L->ci->u.l.pc = &pc;

i.e. &pc is a pointer into the VM C stack.

This means you cannot, for instance, call a  C function, which calls Lua
to create a coroutine and then resume your coroutine (once), yield and
return to C, then resume the coroutine through C from a different point.

For example if you have initialisation code that creates coroutines and
calls them once, perhaps to initialise themselves, those coroutines
cannot be resumed from your main loop because the C stack will be
different.

Please correct me swiftly if this is wrong. If this is true, it should
have been pointed out in the manual, and is a severe limitation/bug in
Lua.

I'm looking at a pretty heavy refactoring is this is true. I guess the
first call, and the initialisation code, could be moved to an init()
function in the script. Then the resume called in the main loop for the
first time to make sure the C stack is the same. Mmmmm.

Nick