lua-users home
lua-l archive

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


On Thu, 2005-02-17 at 01:01, Mike Pall wrote:
[PATCH discussion]

I've just been looking in the Wiki at this patch.
This seems quite interesting, because it might enable
proper cooperation between Felix and Lua coroutines.

In particular, example EXAMPLE 5. Roughly speaking,
this is the model used by all Felix procedures.
In particular, it already does an advanced version
of #5b using computed gotos when GCC is available.

There are two obstacles I see though. First, you can't
use local variables. This is a general problem which
happens not to really apply to Felix (which uses C++
non-static members instead of locals). However this
might impact other user code. 

More precisely, locals have to be declared *before*
the jump to the resume point, and their values extracted
from the lua_State object, and, before you can yield,
you have to store these locals back into the lua_State object.
[Obviously this is a very crude hack to make C do something
C++ can do naturally]

The other problem is the continued use of setjmp/longjump
which isn't C++ compatible.

However there is some hope this mechanism will now allow
fully automatic wrapping of arbitrary Felix procedures.
I'm not sure if this could be done before this patch or not.

In Felix, the whole state of a 'thread' is identified
by a single pointer .. in the middle of a procedure
execution the 'this' pointer of the C++ class object
already encapsulates the location in the code.

The 'switch' of example #5 is already built in.
So we're looking at something like this:

int lua_Felix_Resume(lua_State *L) {
  con_t *state = lua_vcontext(L); // get the this pointer
  state = state->resume(); // call procedure until it yields
  return lua_vyield(L,0,state);   // yield back to Lua
}

Conveniently, Felix 'resume()' signals end  of the thread
by returning NULL, which lua_vyield() also respects.

This example is a very boring one, because the
Felix yields are all 'polite', which makes the 
code a standard procedure. More interesting
is Felix procedures that do blocking reads.
This is detected like so:

	state = state->resume();
	if (state->action) == con_t::wait_action)
	{
		void *msg_address = state->p_message;
		// somehow store a message at this address
		state->action = con_t::yield_action;
	}

which stores the next 'event' at the nominated address.
Typically, we need to yield, and NOT resume until
the event is store there.

The interesting thing about Lua here is that the 'event'
can be assumed to be stored on the Lua stack. So the
type of the message would actually be a lua_State*,
and the Felix procedure would then use the Lua CAPI
to fetch information about the event.

Using Lua this way would provide great flexibility
in the structure of event data... the whole Lua
system is available.

I'm still not sure how to do all this though..

-- 
John Skaller, mailto:skaller@users.sf.net
voice: 061-2-9660-0850, 
snail: PO BOX 401 Glebe NSW 2037 Australia
Checkout the Felix programming language http://felix.sf.net