Front page | perl.perl6.internals |
Postings from February 2002
The Perils of set and PMCs
Thread Next
From:
Simon Cozens
Date:
February 11, 2002 15:07
Subject:
The Perils of set and PMCs
Message ID:
20020211231030.GA10165@netthink.co.uk
Are you sitting comfortably? Then I'll begin.
It's a pretty simple concept. We need to assign one PMC to another.
We'll have to do it all the time:
$a = $b;
$a and $b are both PMCs, and we need to set the value of one to the
value of the other, so let's write it as
set P1, P2
Excellent. Until, of course, we have to implement it. We'll implement
it by calling some vtable method on P1, that much is obvious. But which
one? Our implementation of the set_p_p op can't know whether or not P1
wants a string, an integer, or a number. Or something entirely different.
Indeed, P1 might not know what it wants unless it knows what P2 has to
offer.
So our implementation of set_p_p op has to ask P1 "what do you want out of
P2". And so we need a new vtable op which takes a source PMC, extracts the
appropriate value out of it, and sets a destination PMC to that value. OK so
far? Here's the top-level part of it looks:
inline op set_p_p(PMC*, PMC*) {
$1->vtable->set_pmc(interpreter, $1, $2);
}
Easy, really. Until it comes to implementing that vtable method.
For simple cases, it's fine. For instance, when we're doing PerlInt,
we know that we want an integer, so we can say:
void set_pmc (PMC* value) {
SELF->cache.int_val = (INTVAL)value->vtable->get_integer(INTERP,
value);
}
Fine. But what if P1 could take multiple types and do different things
with them? In that case, which is more common than you think:
%foo = @bar;
P1 can't know what it wants out of P2 unless it knows what
P2 *is*! Just as we couldn't use set_integer, set_number or set_string to
implement our set_p_p op, we can't use get_integer, get_number or get_string
on P2 when we implement set_pmc. Oh boy, it gets crazier and crazier.
So our implementation of set_pmc has to ask P2 "what sort of data can you
offer me"? And so we need a new vtable which takes a PMC and gets some
appropriate value out of it, and our implementation of set_pmc looks like
this:
void set_pmc (PMC* value) {
set_myself(SELF, value->vtable->get_pmc(INTERP, value));
}
And now SELF can probe the "value" PMC at leisure.
Which is fine, so long as we know that "value" ought to give us some
kind of PMC value. (Why would we use get_pmc on a PMC? Well, we wouldn't,
but we'd definitely use get_pmc_keyed(PMC, KEY) on an array, for example.)
So let's say we have
set P1, P2[0]
which may translate to
set_myself(SELF, value->vtable->get_pmc_keyed(INTERP, value, key));
In an ordinary Perl array, we'd have this get_pmc_keyed thing returning
us more PMCs, and it all works out. If, however, we've got an optimized
array of INTVALs, the keyed thing that we get isn't going to be a PMC,
and I'm buggered if I'm letting anyone create PMCs at runtime like this
just so they can be passed around. What we really want is for get_pmc_keyed
to return an INTVAL in that case. But if we have something that we want
to sometimes return PMCs and sometimes return INTVALs, we also need to
return a type as well so we know what we've got. We already have a
structure which encodes value and type - it's called a KEY_PAIR - so I
propose we use that.
Oh yeah, while I'm trying to confuse you all, sometimes we want to
assign one PMC to another by a pointer copy, and sometimes we want
to clone them. Work *that* one out.
--
<gnat> TorgoX: you're rapidly learning, I see, that XML is a fucking
piece of festering shit which has no more justification for walking
God's clean earth than a dung beetle with diarrhoea.
Thread Next
-
The Perils of set and PMCs
by Simon Cozens