So, one of the biggest mysteries for me about Gamestudio is wait(), I have talked with quite a few people about it and no one really has a good idea how it works internally. Although it's commonly agreed to be one huge dirty stack hack.
From what I can see, a call to wait() isn't just a simple function call because it returns the currently running function. Instead I think it's actually more like a macro that expands into something like:
if(notifyScheduler(&stackTop, n) == 0)
return;
The scheduler will then take the current stack pointer and simply copies everything from stackTop down to the current stack pointer into a buffer. StackTop is the address of the first argument that was pushed on the stack, which is also the reason for a) the interesting layout of local variables on the stack (and their weak scope) as well as b) the not existence of variadic functions (if variadic functions would exist, the compiler had to compile multiple versions of the function for each possible number of arguments).
The return address might be passed as well to the scheduler, but I guess it's much easier to just grab it of the stack upon entry, it's also much more accurate and doesn't require work from the linker.
I'm not too sure if some of the registers need to be saved as well, I tried to think of a few good reasons but as far as I can see it's impossible to call wait() from somewhere when there is data in the registers that isn't saved already somewhere.
The scheduler then creates a new entry, saves my and you along with the buffer and return address and that's it.
Then the main runloop finishes it's current step, everything is rendered etc, and then the scheduler kicks in on the next iteration and works off it's list checking which functions are due. I guess what happens there is that it grabs the current stack pointer, modifies the return address on the saved stack, moves something else than zero into eax (to make my pseudo code above work) and then copies the saved stack on the current stack and also restores my and you. Then it makes a jmp to the stored return address and thats it.
At least that's how I imagine it works from all I can see, but what would really interest me: How close is that to the truth? How does wait() actually work?