I'm sick of doing doco stuff so I need a break for a while.
So here's what I'm thinking:

1. Create a type for labels. So you can do this:

        var lab : label;
here:>>
        code_stuf;
        lab = here; // label assignment
        stuff;
        goto *lab; // computed goto

Felix already does this in the C++ code. For gcc (and clang) we use
a void * as the label type and a gcc extension computed goto which
is literally as written above: goto *lab. If there's no support, we just
use an integer, the label gets replaced by

        case 42:

and lab becomes an int variable and the assignment is 

        lab = 42;

To make this one work we change the goto to say:

        pc = lab;
        goto start;

and start says:

        switch (pc) { ...   case 42: ... }

All this works right now, its how Felix procedures work. Macros choose
which implementation (the compiler doesn't know). Long jumps also try
to use "assembler labels" which is also gcc hackery.

Yes, I know gotos are bad and computed gotos are really bad. 
Only, no, they're not, they're completely fundamental basics :)

2. Now I will add a new instruction:

        BEXE_exchange (ptarget, psave)

ptarget and psave are expressions which point to label variables.
The instruction fetches ptarget, store the return address at psave,
sets the program counter to the fetched target, and returns to the driver.
The driver then executes the procedure's resume() which causes the
target to run.

So this instruction is precisely a goto, except the old location is
also saved so we can jump back later. We could also just
do an ordinary goto (with a computed target).

This all assumes the jump is into the current procedure.
It allows you to zig-zag around the code.


3. To handle foreign procedures, we do the same, except now
we have to return the "this" pointer of the foreign procedure,
and set the PC of that procedure instead of the current one.

NOTES
======

The reason for doing this is to natively support coroutines
directly in the Felix code. This does not solve the original
problem, which is how to *inline a generator*. However it does
provide the tools required to do that, so the compiler can later
be modified to do the inlining using the same mechanism
the user would write.

It's likely this generalisation of the *existing* technology will have
major benefits. In particular the execution model may well get
modified. At present each procedure has a PC variable,
so the pair

        this, PC

is the program counter. There is also another variable

        return_address

which is the this pointer of the caller. The PC inside the caller
is stored in the caller. So its not re-entrant. Although this could
be split out, there are two problems: it requires an extra heap
allocation, and, the benefits of "restartable" continuations are limited
to functional continuations because functional code cannot modify anything.

In procedural code, the state data gets modified so "restarting" a procedure
will always get "whatever the current variables hold". So restarting
"from the top" is meaningless. This is why Felix actually clones
functions (to get freshly initialised local variables), and explains
what a generator is: a function that *doesn't* clone its prototype.
So I don't see much benefit in splitting the program counter out
of the data frame at the moment.

Actually I see more benefit in splitting some data out of the frame.
In other words, when you return a closure, instead of just a pointer
into the parent context frame to get at variables, use pointers to
the variables. Now we can happily copy the pointer up, and get
rid of the pointer to the parent frame. The benefit is that when 
we do a long jump we don't have to "unwind the stack". We have
to do that now to breaks cycles, otherwise a pointer to a deeply
nested frame will cause the whole call chain to be reachable,
so Felix NULL's out the return addresses to break the cycles.
This problem would "go away" entirely if the control object
*contained* a pointer to the data frame, instead of being
embedded in it.



--
john skaller
skal...@users.sourceforge.net
http://felix-lang.org




------------------------------------------------------------------------------
WatchGuard Dimension instantly turns raw network data into actionable 
security intelligence. It gives you real-time visual feedback on key
security issues and trends.  Skip the complicated setup - simply import
a virtual appliance and go from zero to informed in seconds.
http://pubads.g.doubleclick.net/gampad/clk?id=123612991&iu=/4140/ostg.clktrk
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to