Hi,

On Wed, 19 Dec 2018, Ryan Joseph wrote:

> > On Dec 19, 2018, at 5:23 PM, Sven Barth via fpc-pascal
> > <fpc-pascal@lists.freepascal.org> wrote:
> >
> > A library as first step would be more useful. Later on one can think
> > about integrating it into the language itself.
> >
>
> How does that work? I’ve been interested in coroutines for a while now
> but I don’t understand how they function in the language. They would
> need to manage stack states and push/restore stacks, which is something
> a library can’t do right?

(After reading that old thread we had...)

Actually, it can. The only thing you need to do is to allocate a stack
first, then make the "coroutine" functions use it, which is basically
boils down to how you pass your arguments and self instance to the
coroutine on initializatin, while you change the stack pointer register,
and then how you restore it in the end. It might be messy, with small bits
in platform-specific assembly - actually the compiler or the RTL could
indeed help a bit there, but this is not a requirement - but theoretically
possible, on the other hand I have absolutely no clue from the top of my
head how that would interfere with any sort of debug info generation,
and/or exception handling.

Actually, if you check the Amiga startup code in the RTL, that already
does this, as AmigaOS and similar systems have a single address space
approach, with a limited size stack, so the RTL startup code checks if the
stack is big enough, and allocates a new one if it is too limited for the
application to run. The OS provides the necessary stack-swap functionality
there, while storing the old stack values for reuse in a small structure,
but this code could just as well be in the application, or your library in
this case. Then the code utilizes setjmp/longjmp to restore register state
on exit, before it quits and restores the old stack.

https://github.com/graemeg/freepascal/blob/master/rtl/morphos/si_prc.pp#L47

https://github.com/graemeg/freepascal/blob/master/rtl/amiga/m68k/si_prc.pp#L60

So to sum it up, after you set up a separate stack and stack pointer
register to your coroutine, the previously discussed setjmp/longjmp method
should work for switching between them.

(Also, if you set up some example-library framework, I might be able to
help with getting the stackswap thing running, if you are not too
comfortable with that. Even if I think this entire coroutine idea is just
a too big of a can of worms to integrate into a compiler/language and a
standard library, but as a separate library it might have its uses
indeed.)

Cheers,
--
Charlie
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to