I'm stuck at a fork in terms of how to fix this particular GC problem.

First, I changed all the direct vtable changes to use morph(). Morph does
a: destroy(), vtable change, and an init(). This is required because some
PMCs require GC-related initiailization, such as PerlStrings, which need
to stick a String in the data pointer, and set the buffer_pointer flag.

Now take 'concat P0, P0, P0', where P0 is a PerlString. It needs to be
implemented as:
dest->vtable->morph(interpreter,dest,enum_class_PerlString);
dest->data =
        string_concat(interpreter,
                  pmc->data,
                  value->vtable->get_string(interpreter, value),
                  0
                 );

The problem with this, is that by the time it goes to concat, the string
has been lost due to morph'ings init(). The hack fix to solve this is to
store the result of the concat in a temp variable, morph dest, and then
set its data field. But this could cause problems where the temp var gets
GC'ed during the morphing init(). Immortal/immune could be of help here,
but I don't think this is heading in the right direction, since it's just
making the programmer's life too confusing.

A second approach is to throw out this weird transmogrifying class stuff,
and just construct a new PMC of the appropriate type to put into the
destination register. Why would we *ever* care what's in the destination
register, since it never gets it's vtable methods called. We just go in
and blow it's data away anyway. With the GC system we have now, we can
leave PMC headers sitting on the wayside, and it will get collected. So if
we construct a new PMC of the appropriate type to store into the
destination register, it becomes GC-safe, easier to program, and we don't
need to 'set' a new PMC into the dest register before we operate on it.

I'm not sure what the original reasoning was for the way things are now,
but I didn't want to go through and change the way the things worked
without checking to be sure it's the right thing to do. Anyone have any
objections to changing around the perl* classes to work this way?

Mike Lambert

Reply via email to