From: Christopher C. <cc...@mu...> - 2005-03-01 16:48:27
|
Florent Hivert <flo...@un...> writes: > new(coroutine, new(coroutineStack), NIL, proc() ... end, NIL) > How do you like it? Looks really nice -- if I could believe that there was an easy way to make it "really" work. :-/ (But isn't what you are doing actually implementing continuations? I must confess I'm still a bit fuzzy on the details of the distinction. http://c2.com/cgi/wiki?ContinuationsAndCoroutines http://rubygarden.org/ruby?ContinuationExplanation ) > Well, up to a point :-( They only works at the interactive level. As I'm surprised to see that much working. I wouldn't trust it too much -- does it still work if you do some other calls in between, or does it just happen to use freed-but-not-overwritten memory? > Our (blind) analysis is that the MuPAD function call stack is stored > globally, and not in the C stack, and is thus not properly duplicated > by makeContext. Not quite. Or rather, in a pretty indirect way, yes. There is no extra stack maintained for this information, but the context (the dynamic scope) is stored in MuPAD memory which is freed when leaving the function. What you can do, of course, is something like corot := proc() local i; option escape; begin i := 0; proc() begin while i < 3 do i := i+1; // "yield" return(i); end_while; i := FAIL; end_proc: end_proc: 3.1.0 > f := corot(): 3.1.0 > f() 1 3.1.0 > f() 2 3.1.0 > f() 3 3.1.0 > f() FAIL This should be enhanced with a little syntactic sugar, sure. Unlike C++, where you can do nasty stuff like void coroutine(int &t) { static enum {s1, s2} state = s1; switch(state) { case s1: while (t) { f1(t); state = s2; return; case s2: f2(t); f3(t); state = s1; return; } }; } (or something very similar, I don't really wish to remember such unmaintainable code), in MuPAD you can't jump into a while loop, so the above approach works only in sufficiently simple cases or with considerable effort, somehow defeating the purpose of having coroutines in the first place. Obviously, if you restrict the places where yield calls may occur, a pure library implementation becomes feasible, but the general transformation, while possible, would be a complicated mess. > beer. Alternatively, we would be happy (?) to (try to) find a solution > by ourselves by browsing through the sources of the kernel. Personally, I'd happily invite you -- but I'm definitely not the guy to decide this. And I somehow doubt that you'd really be happy trying to find something in this code, at least the first three or four times. :-) The routine responsible for evaluating a function currently has something over 500 lines, and it is not even responsible for evaluating the body of the function. Memory management gets pretty tricky around there, and the interaction of coroutines and remember tables and saved DOM_IDENTs I haven't even started to think about. > PS: a funny application (file stack.mu) I somehow believe that there is a faster way of implementing stacks in MuPAD ... :-) -- +--+ +--+| |+-|+ Christopher Creutzig (cc...@mu...) +--+ Tel.: 05251-60-5525 |