Simon Cozens <[EMAIL PROTECTED]> writes:
> 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
Question:
Is there really a one to one mapping between this Perl-instruction and
this Parrot bytecode?
As far as I read the documentation (But I normally read it to fast and
interpret things that aren't actually there) set_p_p is a pointer
copy. For a value copy (aka deep copy) clone is used.
If we set e.g. a PerlInt to a PerlString we would do something like
this:
clone P1, P2
morph P1, PerlString # I know there is no such op
But this transfers the problem only to morph function which has to
know how to morph into every type.
> 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);
> }
This is the other way around. In C++ this would be a constructor while
the morph version would be a cast operation.
> 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*!
If P2 is a known type P1 can simply do
switch (Parrot_base_classname_hash->vtable->get_integer_index_s(NULL,
Parrot_base_classname_hash,
value->vtable->name (NULL, NULL))
this konstruct is nessecarry because there is no class method in the
vtable and type (which I first wrongly assumed to return its class)
method always returns 0.
> 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.
How far does this help? value is already a PMC. What information about
SELF should value->vtable->get_pmc have that value not already has?
> 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.
Really? "You asked for a pointer but, I only have an integer handy so
I give you this". I think it should fail, throw an exeption, return an
NULL pointer or an Undef value or something like this.
> 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.
Maybe its just me, but I find KEY_PAIR a very confusing name for a
general purpose multi_type return value. And I find it confusing to
call a function get_pmc if I get an KEY_PAIR.
> 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.
We need diffrent operations for diffrent kind of things
* set or set_pointer
* set_value or lets call this one set
* clone (maybe this is just a special form of set_value)
Or we just force that every PMC is unique, and there are no pointer
copys at C level. If we want a pointer we have to use a PMC of type
ParrotPointer. Maybe this is stated somewere in the docs, but I fail
to find it (In that case I appologize for my inability to read)
bye
juergen
--
Juergen Boemmels [EMAIL PROTECTED]
Fachbereich Physik Tel: ++49-(0)631-205-2817
Universitaet Kaiserslautern Fax: ++49-(0)631-205-3906
PGP Key fingerprint = 9F 56 54 3D 45 C1 32 6F 23 F6 C7 2F 85 93 DD 47