lua-users home
lua-l archive

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

> > 
> > f(1)
> > f(2)
> I think you meant "c(1)" "c(2)" on the above two lines?

Yes, my mistake.

> I think, rather than needing a language change, you can get the effect
> you want with some wrapper code:
> function make_c_caller()
> 	local t = {}
> 	local function f()
> 		while true do
> 			print(t[1]);
> 			coroutine.yield()
> 		end
> 	end
> 	local c = coroutine.create(f)
> 	local function c_caller(arg)
> 		t[1] = arg;
> 		c()
> 	end
> 	return c_caller
> end
> c = make_c_caller()
> c(1)
> c(2)
> Hopefully that gives you some ideas.

Yes. I can see cases where I can make use of such technique.
However, for performance reasons, I'd rather have f() receive its arguments
on the stack rather than having to store them in a table (which on top of
that will be scanned during garbage collection cycles, thus adding to the gc
load), just to read them back again. I'd much rather have arguments moved
from the coroutine's stack into the coroutined function's. I have
successfully changed LUA in order to do this, and the change is rather
small. The only modification in the core is a 'p' case in lua_getinfo() to
retrieve the exptected number of arguments in a function's prototype, the
res of the modifications is in the coroutine library implementation.

Moreover, this change does not modify the current behaviour, but only
extends it. In practice, you get:

function f(a,b,c)
	while true
		print ( a .. b .. c )
		coroutine . yield ( )

c = coroutine . create (f,"lua ","is ","great!")

c() -- call f() with the args provided at coroutine creation
--> lua is great!
c("Alex Barros ") -- call f() with the provided args on the stack replacing
the previous ones (if provided)
--> Alex Barros is great!
c() -- call f() with the last provided args
--> Alex Barros is great!

All I had to do is retrieve the number of expected arguments in f()'s
prototype, store the number of arguments inside the coroutine userdata in
addition to the thread's address, and each time the coroutine is called,
move the arguments it received into the stack of its coroutined function.
All that remains to do is a bit or error handling, and the handling of
variadic LUA functions and C functions (whose prototype cannot know how many
arguments it expects. BTW, it might not be a bad idea to be able to specify
this at function registration :-).
So, if lua authors are interested, I'll happily provide them with my changes
so that they can have a look at it. If not, I'll simply have to put them
back into 5.0 final when it becomes available.