Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

subclassing bug

6 views
Skip to first unread message

Jens Rieks

unread,
Mar 2, 2004, 4:20:20 PM3/2/04
to perl6-i...@perl.org
The following code results in a
clone() not implemented in class 'ParrotClass'
error:

.sub _main
.local pmc a
.local pmc b
.local pmc c

newclass a, "A"
subclass b, a, "B"
subclass c, b, "C"
end
.end

jens

Simon Glover

unread,
Mar 2, 2004, 7:37:50 PM3/2/04
to Jens Rieks, perl6-i...@perl.org

A PASM version of the test case is:

newclass P16, "A"
subclass P16, P16, "B"
subclass P16, P16, "C"
end

I think I've figured out what's happening here. Stepping through the
code with gdb shows that the first subclassing works fine, but the second
blows up in Parrot_single_subclass at line 233:

temp_pmc =
VTABLE_clone(interpreter,
VTABLE_get_pmc_keyed_int(interpreter,
(PMC *)PMC_data(base_class), PCD_ALL_PARENTS));

This fetches the parent class's parent array, which is an Array PMC,
and which at this point contains a single entry -- a ParrotClass PMC
corresponding to class "A".

We then call the clone method of this array, in order to copy it to
temp_pmc.

This in turn calls list_clone in order to copy its data, and since our
list is comprised of a single PMC, list_clone calls its clone vtable
method.

BUT: this PMC is a ParrotClass, and there isn't currently a clone method
implemented for ParrotClass, so we fall back on the default option, which
is to throw an exception and die.

The only reason that this works the first time that we create a subclass
is that at that point the parent's parent list is empty.

An obvious fix for this would be to implement a clone method for
ParrotClass, but I'm not sure if this really makes sense, as we could
then potentially end up with multiple PMCs representing the same class.
(Also, implies that objects in deeply nested classes would have a
considerable memory overhead, since they'd each have to drag around PMCs
for each of their parent classes).

Simon

Leopold Toetsch

unread,
Mar 3, 2004, 3:35:44 AM3/3/04
to Jens Rieks, perl6-i...@perl.org
Jens Rieks <par...@jensbeimsurfen.de> wrote:
> The following code results in a
> clone() not implemented in class 'ParrotClass'

Can cou try to add this to parrotclass.pmc:

PMC* clone() {
return SELF;
}

> jens

leo

Dan Sugalski

unread,
Mar 3, 2004, 9:34:38 AM3/3/04
to Simon Glover, Jens Rieks, perl6-i...@perl.org
At 7:37 PM -0500 3/2/04, Simon Glover wrote:
> I think I've figured out what's happening here. Stepping through the
> code with gdb shows that the first subclassing works fine, but the second
> blows up in Parrot_single_subclass at line 233:
>
> temp_pmc =
> VTABLE_clone(interpreter,
> VTABLE_get_pmc_keyed_int(interpreter,
> (PMC *)PMC_data(base_class), PCD_ALL_PARENTS));
>
> This fetches the parent class's parent array, which is an Array PMC,
> and which at this point contains a single entry -- a ParrotClass PMC
> corresponding to class "A".
>
> We then call the clone method of this array, in order to copy it to
> temp_pmc.
>
> This in turn calls list_clone in order to copy its data, and since our
> list is comprised of a single PMC, list_clone calls its clone vtable
> method.

Ah, I was thinking it was a single-level clone of data--basically a
shallow copy. I'll go fix.
--
Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk

Leopold Toetsch

unread,
Mar 3, 2004, 4:51:58 PM3/3/04
to Dan Sugalski, perl6-i...@perl.org
Dan Sugalski <d...@sidhe.org> wrote:

> Ah, I was thinking it was a single-level clone of data--basically a
> shallow copy. I'll go fix.

I still don't know, how deep vtable->clone should really go. Currently
its of course still borken: it clones recursive-deeply and fails on
self-referentials structures. But that is handled by Parrot_clone() which
uses freeze/thaw.

Back to the original problem: Is there any reason not to just have

PMC* clone() {
return SELF;
}

in parrotclass.pmc? A class is a class, nothing to duplicate IMHO.

Anyway, we need a way to specify somehow, how to clone or have two
vtables or opcodes to deal with that. Duplicating thread arguments also
needs (very likely) a deep clone.

leo

Dan Sugalski

unread,
Mar 4, 2004, 10:29:43 AM3/4/04
to Jens Rieks, perl6-i...@perl.org

Steve was right -- the clone I was using was getting in the way. (And
flat-out busted, honestly) Only a shallow copy of the parent class'
array is needed here, so I put in a bit of custom code rather than
use the clone and it works properly now.

Simon Glover

unread,
Mar 7, 2004, 12:03:56 PM3/7/04
to Dan Sugalski, perl6-i...@perl.org

On Thu, 4 Mar 2004, Dan Sugalski wrote:

> At 10:20 PM +0100 3/2/04, Jens Rieks wrote:
> >The following code results in a
> >clone() not implemented in class 'ParrotClass'
> >error:
> >
> >.sub _main
> > .local pmc a
> > .local pmc b
> > .local pmc c
> >
> > newclass a, "A"
> > subclass b, a, "B"
> > subclass c, b, "C"
> > end
> >.end
>
> Steve was right -- the clone I was using was getting in the way. (And
> flat-out busted, honestly) Only a shallow copy of the parent class'
> array is needed here, so I put in a bit of custom code rather than
> use the clone and it works properly now.

Which leads me to ask a question that I've been pondering for a while
-- do we actually need to use a fullblown Array PMC to hold the object
meta-information and attributes? Couldn't we save a level of indirection
(and one PMC header per object) by using a List structure directly?

Simon

Dan Sugalski

unread,
Mar 8, 2004, 11:37:24 AM3/8/04
to Simon Glover, perl6-i...@perl.org
At 12:03 PM -0500 3/7/04, Simon Glover wrote:
> Which leads me to ask a question that I've been pondering for a while
> -- do we actually need to use a fullblown Array PMC to hold the object
> meta-information and attributes? Couldn't we save a level of indirection
> (and one PMC header per object) by using a List structure directly?

Nope, we don't need it. We can go one less level of indirection than
List, too, since we don't need the info it provides either, as the
entries are guaranteed to be PMCs. We can hang a bare PMC buffer
(well, OK, PArray, but they should be the same thing) off the object,
and directly poke at its internals.

Leopold Toetsch

unread,
Mar 8, 2004, 12:05:21 PM3/8/04
to Dan Sugalski, perl6-i...@perl.org
Dan Sugalski <d...@sidhe.org> wrote:

> Nope, we don't need it. We can go one less level of indirection than
> List, too, since we don't need the info it provides either, as the
> entries are guaranteed to be PMCs. We can hang a bare PMC buffer
> (well, OK, PArray, but they should be the same thing) off the object,
> and directly poke at its internals.

As already mentioned in a private mail WRT object layout, we could have:

obj->vtable->data := class PMC
Pobj_bufstart(obj) := classname STRING
Pobj_buflen(obj) := attribute count
PMC_data(obj) := struct List* of attributes

Such a layout is much more compact then the current one. It would need a
custom mark function and an overriden C<name> method, that's all AFAIK.

leo

0 new messages