On Nov 13, 2005, at 4:45, Chip Salzenberg wrote:
{ First, let's have a little applause for Leo for implementing the new
lexical scheme in, what, a week? He says it was only a half-day's
work, too. Nice work, dude! }
It was just half a day. The rest of the week was spent on unicode
improvements along with various fixes and cleanup in strings, charsets,
and encodings. The register allocator was already prepard in advance to
deal with the allocation of lexicals (another ~2 hours).
etc. We'd probably only need one new opcode, if that: something like
$P0 = callframe
to return the current call frame, which could then be walked with
get_caller(). I suppose we could toss it a version that takes an
INTVAL like:
$P0 = callframe 1
to walk up that many frames.
We already have this kind of introspection: $ grep caller t/pmc/sub.t
(We can invent better syntax for it though [1])
Now on to the questions, mostly for Leo:
[ callframe as PMC ]
[ ... ]
... This seems like the best
choice, assuming GC issues are manageable.
This would be an enormous can of worms IMHO. The main problem is: no
one guarantees that a callframe PMC just stays in the subroutine, where
it is created. You could store the callframe PMC into globals, return
it from the sub, whatever. *If* the subroutine was left via a plain
C<returncc> the data of the callframe (Parrot_Context and register
space) are recycled immediately, but the callframe would still point to
it.
OTOH treating a callframe PMC as "normal" PMC would mean that its
contents is kept alive as long as the callframe PMC lives. This would
make timely destruction near to impossible in the case of an existing
callframe PMC.
The liveness of callframes is currently managed solely by
continuations, which makes this rather straightforward. A
RetContinuation can be used exactly once and the callframe is recycled
immediately. Creating a user accessible Continuation switches callframe
live-management to reference counts. And all the callframes up the
callchain have their RetCcontinuations converted to Continuations too
[2]. When the last continuation refering to a callframe dies, the
refcount reaches zero and the callframe gets recycled.
Complicating this already nasty stuff just for introspection is not a
good idea.
[1] I'd use just methods, either on the interpreter or a sub pmc:
interp."get_caller"(n_levels) # interpreter method or
sub_class = getclass 'Sub'
sub_class."get_caller"(n_levels) # class method 0 = this sub, 1 =
caller, ...
a_sub."get_caller"(nlevels) # obj method, if you already have
a sub
[2] A delimited continuation (shift/reset) would make this less
expensive
leo