develooper Front page | perl.perl6.internals | Postings from October 2001

PMCs and how the opcode functions will work

Thread Next
Dan Sugalski
October 8, 2001 15:36
PMCs and how the opcode functions will work
Message ID:
Okay, here's a quick rundown on PMCs and how we're handling opcodes called 
on PMC registers. (This is mildly different than what's gone in the past, FWIW)

Every PMC has a set of static types, stored in the vtable. These types are 
static, and stuck in the base vtable structure, which looks like:

   struct _vtable {
	PACKAGE *package;
	INTVAL	base_type;
	INTVAL	int_type;
	INTVAL	float_type;
	INTVAL	num_type;
	INTVAL	string_type;
        void *(*vtable_funcs[VTABLE_SIZE])()

(cdecl's responsible for the function pointer table declaration, so I 
expect it's right for what I told it, but I might've told it wrong)

There are several entries for each function, and the one that's called 
depends on the type of the second argument. The types are:

   base_type: A unique identifier attached to the package. 0-INTVAL_MAX
   int_type: 0, 1, 2, 3 for "same as you", native int, bigint, object
   float_type: 0, 1, 2, 3 for "same as you", native float, bigfloat, object
   num_type: 0, 1, 2, 3, 4, 5 for "same as you", native int, bigint, native
	     float, bigfloat, object
   string_type: 0, 1, 2, 3, 4 for "same as you", native string, unicode,
	        other, object

The 'object' entry is used when a PMC isn't willing to classify itself 
definitively as a string, integer, float, or number type. In that case a 
multimethod dispatch is generally used to find out what the 'right' thing 
to do is, though the vtable code is allowed to just say "Give me yourself 
as an integer, darn it!"

for a simple add:

    $foo = $bar + $baz;

the assembly looks like (assuming we've got $foo, $bar, and $baz in 
registers already):

    add P0, P1, P2

the call will be:

     P1->vtable_funcs[VTABLE_ADD + P2->num_type](P1, P2, P0);

and inside the add function P0 gets its "assign to" vtable method called, 
in case $foo's been overloaded. Which type an entry group takes depends on 
the entry. Concat takes strings, math ops take numbers, and so on.

Now, that does mean we have a lot of vtable entries. At the moment I'm OK 
with that, though if it turns out that having a single ADD entry that does 
lots of checking is a win over a half-dozen different special-purpose add 
functions, we'll do that.

There's a list of proposed vtable functions kicking around. We'll start 
with simple ones and go from there.

References have a fancy reflecting vtable that vectors (when appropriate) 
through the vtable of the referent. But we'll get to that another time.

Now, I'm sure you're all thinking "But what about aggregates?" (No, really, 
you were. You just might not've known it... :) Well, that's where things 
get interesting.

Because we can't guarantee that individual entries in an array actually 
have PMCs attached to them, we vector all access to aggregate entries 
through the aggregate's vtable and leave that vtable to sort things out. 
Each type (int, float, num, string) has an entry past 'object' that's 
special. That function is still an add, subtract, concat, or whatever, but 
each of the three PMC pointers gets a corresponding key structure passed 
with it.

A key structure looks like:

   struct key {
	INTVAL count;
	INTVAL type1;
	INTVAL type2;
	struct key *chain;
	union entry {STRING *skey1;
	       INTVAL ikey1;
	       PMC    *pkey1;
	union {STRING *skey2;
	       INTVAL ikey2;
	       PMC    *pkey2;

(Though we may make the individual key unions an array, assuming we don't 
hack this down to a single key)

We pass in one per parameter, with a NULL meaning "No, I'm a scalar and not 
an aggregate". If two entries aren't enough the chain is used to point to 
another pair of keys. (Or another single key if we ditch the pairs) The 
"Access aggregate entries" then uses the key structure to find the 
appropriate entry in the aggregate to work on

(The aggregate stuff's a little odd, and subject to change, but I think 
this is what we'll end up with)

Questions, anyone? ;-)


--------------------------------------"it's like this"-------------------
Dan Sugalski                          even samurai                         have teddy bears and even
                                      teddy bears get drunk

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About