Hi all, In my previous mail I did some discussions about what structure to use in order to allow efficient implementatin og generators and one main observation is that the curretn rtl strategy can be used.
Now Have you all thought about the stack beeing a must to execute funcitons. Well we have threads but we can get lightweight in process threads quite naturally in the rtl version of guile. We could call it a coroutine and let it be an object co = (code,stack,ip,outer-stack) The idea here is that the code will have a fixed sized stack that is just enough room to store all locals and intermediate variables e.g. all the registers needed to execute the function. Any call would then need to hook onto the outer stack. The stack is typically of the form stack = [IP OUTER-FP LOCALS ...] At the creation, IP points to the starting code position and then after each exit the next ip is stored in IP and so on. To support this we need a few new operations * MULTIMOVE, from the local stack to outer stack * MULTIMOVE, to the local stack from the outer stack * OUTER-TAIL-CALL This re-uses the outer call frame used to call this coroutine and resets the IP to the initial value * OUTER-CALL This will setup a new call frame on the outer stack execute the function there * RESET-IP RESET the IP value to the initial start value * STORE-IP Store an local ip adress in IP using a label. * OUTER-RETURN Simply return using the OUTER-FP and make sure * CALL-CO This will call a CO routine by setting up the * TAIL-CALL-CO call frame or reusing the current one (in tail context) then set the OUTER-FP and jump to the IP value if a number else throw an error. And then setting IP to #f and start executing This will probably work quite ok. But the question is how well it play with call/cc and classic prompts as well as usage of the same object many times. 1. This object can only be located one time in the stack because when in use IP = #f and another application of the object down the stack would throw an error at the application 2. call/cc prompt code dynwinds and fluids inside co needs to have special versions 3. When one store the stack space one need to make sure that the co routines also get copied. To note is that these objects should be able to live immersed in the stack space for quick allocation when we inline them inside functions. ---------------------------------- Anyway I will explore this concept semewhat more and see if all scheme features can be made to interop in a good way with it. ---------------------------------- I would also come back to the question if we should have a special tree-il concept that can be used to model this behavior. I'm now inclined to concider something like. (lexical-prompts ((g #:exits (a ...) #:body (th thunk) #:exit-case (((a) (lambda (k kind arg ...) code2)) ...)) ...) code ...) The default expansion of this woule then be something like (letrec ((g . l) (let* ((tag (make-tag)) (th thunk)) (call-with-prompts tag (apply th l) (lambda (k kind arg ...) (case kind ((a) code2 ...) ...))))) ...) code ...) So if we can prove: 1. The only references of g ... inside th is through e.g. (a g arg ...) where we mean ( g arg ...) = (abort-to-prompt tag 'a g arg ...). 2. these (a ...) forms is not included in any lambda definitions or entering any funciton via it's argumnets. 3. g is never feeded as an argument to a function or located inside a closure definition anywhere in the form. 4. in ((code2 ...) ...) ... any applications of g ... is located in tail position. 5.th is always setted to either k or the initial thunk or never setted in any of the ((a) ...) forms. with these things satisfied we should be able to inline the co routine or generator inside of the function with quite good characteristic. This is interesting this should be a logically step up in generality from CL's tagbody. Of cause there is a lot of substructure and combination of the general construct. >From the rtl code we would manage just ok with the old instructions just fine except for the need to be be able to store a label value and goto to a stored label value aka named goto. WDYT? /Stefan