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

Problems with new object ops

13 views
Skip to first unread message

Simon Glover

unread,
Jul 16, 2003, 10:38:46 PM7/16/03
to Dan Sugalski, perl6-i...@perl.org

Dan,

I've been playing about with the new object stuff you added today, and
I've noticed a couple of problems.

Firstly, when your doing the initialization for a new ParrotClass PMC,
you create an Array to hold various other PMCs, but you don't size the
array; this means that when you later try to put things in it in
Parrot_new_class, it dies with:

Array index out of bounds!

The simplest solution is just to specify the size, as in the patch below.

------------

The other problem I noticed was that in a bunch of the ops you're using
code like:

PMC *class = VTABLE_get_pmc_keyed(interpreter,
interpreter->class_hash, key_new_string(interpreter, $2));

to get the ParrotClass PMC, and then seeing whether it's a valid class
by checking whether class is NULL. For instance, in findclass, you have:

if (VTABLE_get_pmc_keyed(interpreter, interpreter->class_hash,
key_new_string(interpreter, $2))) {
$1 = 1;
} else {
$1 = 0;
}

Unfortunately, this doesn't do what you intend. When you look up a
non-existent entry in a PerlHash, it creates and returns a PerlUndef PMC,
so the class pointer that you get is always non-NULL, even though it
isn't necessarily a ParrotClass. Consequently, in the example above,
findclass always returns true.

I'm not sure what the best fix is here.

Simon


--- classes/parrotclass.pmc Wed Jul 16 22:28:40 2003
+++ classes/parrotclass.pmc.new Wed Jul 16 22:28:35 2003
@@ -32,6 +32,8 @@
void init () {
/* Hang an array off the data pointer, empty of course */
PMC_data(SELF) = pmc_new(interpreter, enum_class_Array);
+ /* We will have five entries in this array */
+ VTABLE_set_integer_native(interpreter, (PMC*)PMC_data(SELF), (INTVAL)5);
/* No attributes to start with */
SELF->obj.u.int_val = 0;
/* But we are a class, really */


Leopold Toetsch

unread,
Jul 17, 2003, 3:24:39 AM7/17/03
to Simon Glover, perl6-i...@perl.org, d...@sidhe.org
Simon Glover <sc...@amnh.org> wrote:

> Dan,

> Firstly, when your doing the initialization for a new ParrotClass PMC,
> you create an Array to hold various other PMCs, but you don't size the
> array; this means that when you later try to put things in it in
> Parrot_new_class, it dies with:

> Array index out of bounds!

I would use an SArray. Its simpler then an Array. Also the DOD flag is
bogus. An Array is not a buffer of PMCs. Its a ptr to a PMC in data:
PObj_is_PMC_ptr_FLAG.

> .... For instance, in findclass, you have:

> if (VTABLE_get_pmc_keyed(interpreter, interpreter->class_hash,
> key_new_string(interpreter, $2))) {
> $1 = 1;
> } else {
> $1 = 0;
> }

this should be VTABLE_exists_keyed ...

And the second find_class op should be get_class.

And s/obj\.u\.int_val/cache.int_val/g

leo

Dan Sugalski

unread,
Jul 17, 2003, 1:14:03 PM7/17/03
to l...@toetsch.at, Simon Glover, perl6-i...@perl.org
At 9:24 AM +0200 7/17/03, Leopold Toetsch wrote:
>Simon Glover <sc...@amnh.org> wrote:
>
>> Dan,
>
>> Firstly, when your doing the initialization for a new ParrotClass PMC,
>> you create an Array to hold various other PMCs, but you don't size the
>> array; this means that when you later try to put things in it in
>> Parrot_new_class, it dies with:
>
>> Array index out of bounds!
>
>I would use an SArray. Its simpler then an Array.

Point taken, and I've patched the patch from Simon.

>Also the DOD flag is
>bogus. An Array is not a buffer of PMCs. Its a ptr to a PMC in data:
>PObj_is_PMC_ptr_FLAG.

Gah. Thinko on my part. (I really want that thing hanging off the
data pointer to be a buffer not a PMC...)

> > .... For instance, in findclass, you have:
>
>> if (VTABLE_get_pmc_keyed(interpreter, interpreter->class_hash,
>> key_new_string(interpreter, $2))) {
>> $1 = 1;
>> } else {
>> $1 = 0;
>> }
>
>this should be VTABLE_exists_keyed ...

Point. Updated.

>And the second find_class op should be get_class.

D'oh! Fixed too. (This would all be why I don't commit much code)

>And s/obj\.u\.int_val/cache.int_val/g

Ah, I see. Changed as well.
--
Dan

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

Simon Glover

unread,
Jul 18, 2003, 1:34:17 PM7/18/03
to Dan Sugalski, perl6-i...@perl.org

On Thu, 17 Jul 2003, Dan Sugalski wrote:

> At 9:24 AM +0200 7/17/03, Leopold Toetsch wrote:
> >Simon Glover <sc...@amnh.org> wrote:
> >
> > > .... For instance, in findclass, you have:
> >
> >> if (VTABLE_get_pmc_keyed(interpreter, interpreter->class_hash,
> >> key_new_string(interpreter, $2))) {
> >> $1 = 1;
> >> } else {
> >> $1 = 0;
> >> }
> >
> >this should be VTABLE_exists_keyed ...
>
> Point. Updated.

Of course this still doesn't work, because we never actually add anything
to the class_hash. Patch below fixes this, as well as various bugs in
Parrot_single_subclass, and adds a couple of regression tests.

Simon

--- objects.c.old Fri Jul 18 12:09:27 2003
+++ objects.c Fri Jul 18 13:30:14 2003
@@ -31,16 +31,19 @@

child_class = pmc_new(interpreter, enum_class_ParrotClass);
child_class_array = PMC_data(child_class);
+
/* We have the same number of attributes as our parent */
child_class->obj.u.int_val = base_class->obj.u.int_val;
+
/* Our parent class array has a single member in it */
temp_pmc = pmc_new(interpreter, enum_class_Array);
+ VTABLE_set_integer_native(interpreter, temp_pmc, 1);
VTABLE_set_pmc_keyed_int(interpreter, child_class_array, 0, temp_pmc);
VTABLE_set_pmc_keyed_int(interpreter, temp_pmc, 0, base_class);

/* Our penultimate parent list is a clone of our parent's parent
list, with our parent unshifted onto the beginning */
- temp_pmc = pmc_new(interpreter, enum_class_PerlUndef);
+ temp_pmc = pmc_new_noinit(interpreter, enum_class_Array);
VTABLE_clone(interpreter,
VTABLE_get_pmc_keyed_int(interpreter,
(PMC *)PMC_data(base_class), 1),
@@ -49,7 +52,7 @@
VTABLE_set_pmc_keyed_int(interpreter, child_class_array, 1, temp_pmc);

/* Our attribute list is our parent's attribute list */
- temp_pmc = pmc_new(interpreter, enum_class_PerlUndef);
+ temp_pmc = pmc_new_noinit(interpreter, enum_class_PerlHash);
VTABLE_clone(interpreter,
VTABLE_get_pmc_keyed_int(interpreter,
(PMC *)PMC_data(base_class), 2),
@@ -57,7 +60,7 @@
VTABLE_set_pmc_keyed_int(interpreter, child_class_array, 2, temp_pmc);

/* And our full keyed attribute list is our parent's */
- temp_pmc = pmc_new(interpreter, enum_class_PerlUndef);
+ temp_pmc = pmc_new_noinit(interpreter, enum_class_PerlHash);
VTABLE_clone(interpreter,
VTABLE_get_pmc_keyed_int(interpreter,
(PMC *)PMC_data(base_class), 3),
@@ -68,7 +71,13 @@
classname_pmc = pmc_new(interpreter, enum_class_PerlString);
if (child_class_name) {
VTABLE_set_string_native(interpreter, classname_pmc, child_class_name);
- } else {
+
+ /* Add ourselves to the interpreter's class hash */
+ VTABLE_set_pmc_keyed(interpreter, interpreter->class_hash,
+ key_new_string(interpreter, child_class_name),
+ child_class);
+ }
+ else {
VTABLE_set_string_native(interpreter, classname_pmc,
string_make(interpreter, "\0\0anonymous", 11, NULL, 0, NULL));
}
@@ -106,6 +115,10 @@
VTABLE_set_string_native(interpreter, classname_pmc, class_name);
VTABLE_set_pmc_keyed_int(interpreter, new_class_array, 4, classname_pmc);

+ /* Add ourselves to the interpreter's class hash */
+ VTABLE_set_pmc_keyed(interpreter, interpreter->class_hash,
+ key_new_string(interpreter,class_name), new_class);
+
return(new_class);
}

--- /dev/null Thu Aug 30 16:30:55 2001
+++ t/pmc/objects.t Fri Jul 18 13:31:01 2003
@@ -0,0 +1,43 @@
+#! perl -w
+
+use Parrot::Test tests => 2;
+use Test::More;
+
+output_is(<<'CODE', <<'OUTPUT', "findclass (base class)");
+ newclass P1, "Foo"
+
+ findclass I0, "Foo"
+ print I0
+ print "\n"
+
+ findclass I0, "Bar"
+ print I0
+ print "\n"
+ end
+CODE
+1
+0
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "findclass (subclass)");
+ newclass P1, "Foo"
+ subclass P2, P1, "Bar"
+
+ findclass I0, "Foo"
+ print I0
+ print "\n"
+
+ findclass I0, "Bar"
+ print I0
+ print "\n"
+
+ findclass I0, "Qux"
+ print I0
+ print "\n"
+
+ end
+CODE
+1
+1
+0
+OUTPUT

Simon Glover

unread,
Jul 18, 2003, 1:36:54 PM7/18/03
to Dan Sugalski, perl6-i...@perl.org

Of course, if you apply the previous patch, you'll also need to apply
this one...

Simon

--- MANIFEST.old Fri Jul 18 13:35:04 2003
+++ MANIFEST Fri Jul 18 13:35:41 2003
@@ -1861,6 +1861,7 @@
t/pmc/managedstruct.t []
t/pmc/multiarray.t []
t/pmc/nci.t []
+t/pmc/objects.t []
t/pmc/perlarray.t []
t/pmc/perlhash.t []
t/pmc/perlint.t []

Dan Sugalski

unread,
Jul 18, 2003, 2:15:16 PM7/18/03
to Simon Glover, perl6-i...@perl.org
At 1:34 PM -0400 7/18/03, Simon Glover wrote:
> Of course this still doesn't work, because we never actually add anything
> to the class_hash. Patch below fixes this, as well as various bugs in
> Parrot_single_subclass, and adds a couple of regression tests.

Thanks Simon. Applied.

0 new messages