At 04:23 PM 2/6/2001 -0200, Branden wrote:
>Dan Sugalski wrote:
> > At 01:50 PM 2/6/2001 -0200, Branden wrote:
> > >In the approach using the vtables I propose, it would be:
> > >
> > >
> > >  // get the PMC's that correspond to each variable...
> > >  HVAR *foo  = get_hvar("foo");
> > >  SVAR *baz  = get_svar("baz");
> > >  AVAR *xyz  = get_avar("xyzzy");
> >
> > This likely won't be done this way. Variables looked up by name (package
> > and named lexicals (if we even let you look up lexicals by name)) will be
> > handled like this (though we'll probably do a bunch of optimization) but
> > lexicals will not be. The compiler will pre-compute what it needs so we'll
> > have a PMC already, or find them with an array lookup in the appropriate
> > place in the lexical stack.
>
>Sorry 'bout that, it was only to illustrate having the PMC's in C without
>having to mention the compiler, or anything else...

Not generally unreasonable, as the behaviour of the compiler's not been set 
down in stone yet.

> > Well, the code *inside* foo's add would do:
> >
> >    IV lside = baz->vtable->get_int[NATIVE](baz, key+1);
> >    IV rside = xyzzy->vtable->get_int[NATIVE](xyzzy, key+2);
> >    IV sum = lside + rside;
> >
> >    db_store(foo->data->db_handle, KEYSTRING(key[0]), IV_TO_UTF8(sum));
> >
> > And yes, using the KEYSTRING and IV_TO_UTF8 macros to do the conversions
>is
> > a bit of a punt, but that's OK at this point.
> >
>
>I actually don't see anything related to foo here, besides the last line of
>it, which is actually the same as the set_string entry of the same vtable.

That's OK, since my example was wrong. (D'oh! Chalk it up to remnants of 
the martian death flu, along with too much blood in my caffeine stream) The 
example

  $foo{bar} = $baz + $xyzzy[42];

turns into

   baz->vtable->add[NATIVE](foo, baz, xyzzy, key);

with the add routine doing

     IV lside = baz->vtable->get_int[NATIVE](baz, key+1);
     IV rside = xyzzy->vtable->get_int[NATIVE](xyzzy, key+2);
     IV sum;
     bigstr *bigsum;
     CHECK_OVERFLOW(bigstr, (sum = lside + rside));

     if (OVERFLOW) {
       foo->vtable->set_integer[BIGINT](foo, bigsum, key[0]);
     } else {
       foo->vtable->set_integer[NATIVE](foo, sum, key[0]);
     }

and foo's set_integer storing the passed data in the database as appropriate.

>And if we replace that line for the correspondent set_string operation, I
>don't see the need to have add in a vtable, because I cannot understand how
>it could be implemented differently for another variable aside from foo.

Now, as to this...

What happens if you have an overloaded array on the left side? Or a complex 
number? Or a bigint? The point of having add in the vtable (along with a 
lot of the other stuff that's in there) is so we can have a lot of 
special-purpose code rather than a hunk of general-purpose code. The idea 
is to reduce the number of tests and branches and shrink the size of the 
code we actually execute so we don't blow processor cache or have to clear 
out execution pipelines.

>And the line that sums the two values doesn't take into account the fact
>that baz has + overloaded to make some test if the values are strings, to
>concatenate instead of sum. How would foo's vtable have to deal with that?

Well, in the updated (and actually correct... :) version it does, since 
it's baz's add code that gets called. If xyzzy is overloaded things get 
dicier. How that gets handled (when the right operand in an expression is 
overloaded, or both) is a language issue, and one that someone else (read: 
Larry) has to decide.

> > There's nothing wrong with a vtable's function from using the vtable
> > functions of its arguments. It's actually a requirement if the arguments
> > aren't all of the same class.
> >
>
>But the more one vtable has to deal with other vtables, the less code
>re-using and extensibility we have.

Really? Why? There's no reason that multiple classes can't share routines. 
Vtables are just big arrays of function pointers--if multiple classes share 
underlying implementations, there's no reason they can't share the 
functions as well.

[I snipped the next bit, since it was based on a bad example]

> > >In the approach I'm proposing, xyz->vtable->FETCH(xyz_val, xyz, xyz_idx)
> > >would ask for the element indexed 42 of the array. As the vtable used is
>the
> > >one of the array itself, it knows it should fetch it from the directory
> > >listing, and does it. In baz_val->vtable->ADD(foo_val, baz_val, xyz_val),
> > >the ADD method is called from the $baz vtable, so it knows about $baz
>being
> > >overloaded. (Of course overloading this way only applies to the left
> > >operand, I don't know if there's a workaround for this). The ADD method
>gets
> > >the right operand by calling STRING/INT/NUMBER on the last argument. And
> > >foo->vtable->STORE(foo, foo_key, foo_val) is responsible for storing the
> > >value on %foo, using foo_key as the key. STORE is in %foo's vtable, so it
> > >knows it should actually write the data in the DBM.
> >
> > Nothing wrong with that, but there are more op dispatches that way. While
> > that's not a horrible thing, if we can avoid them that's better.
> >
>
>What's exactly a op dispatch? I _really_ don't know that. Please tell me so
>that I can answer this...

Okay, you need to dig into perl 5's interpreter more .

Perl's an interpreter, and perl 6 is going to be no exception. It executes 
a series of opcodes that tell it to do things. Op dispatch is the process 
of dispatching a particular opcode's function, and it's a reasonably large 
part of the cost you pay in perl 5. Shrinking that overhead is a good thing.

> > Don't forget we have an opcode machine here--we are *not* emitting C code
> > to be compiled. That means we're going to be storing temps in a register
> > file of some sort. (Or pushing them on a stack, or whatever) That means
> > that if we generate intermediaries that aren't PMCs then we need extra
>temp
> > space for them. Your way will mean an int, num, and string stack (or
> > register file, or whatever) in addition to a PMC stack/register
> > file/whatever. That's more stuff to track. (Which isn't to say we won't,
> > mind. We will if we have to)
> >
>
>I know that (althought I don't have the exact definition of opcode yet). I
>wrote C code only to illustrate my point.
>
>If a opcode is what I'm thinking, in the fact that the interpreter executes
>a opcode kind of atomically, like a machine instruction in assembly, then I
>would like to say that the entries you are proposing to the vtables are
>probably much better as opcodes than mine. But I'm actually not saying that
>one vtable function call should be a opcode. I mean, an `add' instruction
>could be built above that that would do all that at once, and that could be
>the opcode...

If I was feeling crankier, I'd rant here for a moment. I'm not, though, so 
I won't. (And please, everyone, lets also be a touch restrained)

Perl is an interpreter, one that executes a stream of opcodes. That fact 
*must* be kept in mind, as it places constraints that must be heeded for 
speed. Your scheme may be a bit faster (certainly conceptually simpler) 
than the one I'm proposing for a direct-to-C translator, but we're not 
writing that--we're writing an interpreter. Different beasts.

Think of the perl interpreter as a big CPU, with none of the neato-keen 
tricks available to it that modern designers have. You'll find that the 
design will tend towards a more CISC-like architecture than a RISC-like one.

>I actually don't see a reason why the vtable entries should be the opcodes.
>Is there?

Speed.

> > > > --
> > > > For me, UNIX is a way of being. -Armando P. Stettner
> > > >
> > >
> > >For me too.
> >
> > Just remember that it's not the only way to be...
>
>But I like it!  ;-)

As long as you don't get blinded by like.

                                        Dan

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

Reply via email to