July 07, 2005

Keeping everything in context

This is one of those things that doesn't really have a place in one of the other parrot sub-categories, so I'll just go on about it here.

How the heck was parrot supposed to do context? Context, here, being "what does my caller expect me to return?" For perl 5 this means either scalar (it expects a single value back) or list (it expects multiple values back) but perl 6 made things a bit more complex. (Which is a separate topic, for someone else to talk about)

This was one of the things that really bugged me, and you'll note the glaring lack of context information in parrot's calling conventions. This was very much on purpose -- Larry'd waffled back and forth some on how much context information should be available to subs, and so I'd put it off for a while. This was one of those things that just extending the perl 5 meaning wasn't enough for.

You'll note it never resurfaced, at least not in the calling conventions.

Why? Because it just wasn't needed.

If you look at how parrot calls subs and returns from subs, you'll of course notice that they're done identically. Same registers filled in, same method of invocation, same everything. That's because the way that parrot uses CPS means that calling subs and returning from subs works identically. Return values are just parameters passed in to the return continuation.

Which means that there's no difference between the expected return values and the expected passed-in values for a sub.

Which means that the return context is just the prototype for the return continuation.

So, if you want to figure out what context you were called in, you just need to fetch out the prototype property from your return continuation and you're set.

No muss, no fuss, no fancy nothing.

Granted, this then raises the question of how to specify a prototype for a sub object, but that's a separate question, and one that needs answering anyway, so the answer to it answers the "how do I specify the return context" question.