On Mon, Feb 11, 2002 at 11:10:30PM +0000, Simon Cozens wrote:
> 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.

We'll need to be constructing similar PMCs all the time for other
purposes.

  my @x = qw(1, 'a');
  my int @y = qw(1 2 3 4);
  $x[0] = $y[2];

or

  my int @y = qw(1 2 3);
  f($y[2]);

Unless f is prototyped to take an int, $y[2] needs to be boxed up as a
PMC. Probably even worse -- since it's passed by reference, it should
expand to something like

  convert $y[2] to a PMC P0
  pass P0 to f()
  copy the integer value of P0 back to $y[2]

but that's another story.

But I guess you're talking about a situation where we have to convert
an integer to a temporary PMC just to grab an integer out and discard
the PMC. Hm, confusing sentence.

  P1.set_int(int2pmc(P2.get_pmc_keyed(0)).get_int())

It seems like there are three cases:

  1. Accessing an array of PMCs
  2. Accessing an optimized array of ints where the compiler knows the
     array's type
  3. Accessing an optimized array of ints where the compiler does not
     know the array's type.

You're saying case #3 is frequent enough in conjuction with the
assignment operator that it [assignment] merits being optimized to the
KEY_PAIR discriminated union instead of using a temporary PMC to box
it up?

Following that line of thought, it seems like a PMC is just an
overachieving discriminated union, so why not use a PMC instead of a
KEY_PAIR?:

  void set_pmc (PMC* value) {
      PMC temp;
      value->vtable->get_pmc_into(INTERP, value, &temp);
      set_myself(SELF, &temp);
  }

Call temp an "rvalue PMC" or something. I'm mostly suggesting this
because I have this niggling worry about how PMC value attributes are
going to get copied, and if that means that your KEY_PAIR thing will
end up growing into huge wad that will be just as expensive to
allocate and pass around as a PMC would. An rvalue PMC could have as
restricted a set of possible types as a KEY_PAIR, but might be easier
to hold more than that if necessary.

I hope I'm making sense. I'm not real sure.

Reply via email to