On Saturday, January 24, 2004, at 09:23 , Leopold Toetsch wrote:

Gordon Henriksen <[EMAIL PROTECTED]> wrote:

... Best example: morph. morph must die.

Morph is necessary. But please note: morph changes the vtable of the PMC to point to the new data types table. It has nothing to do with a typed union.

The vtable IS the discriminator. I'm referring to this:


        typedef union UnionVal {
            struct {                    /* Buffers structure */
                void * bufstart;
                size_t buflen;
            } b;
            struct {                    /* PMC unionval members */
                DPOINTER* _struct_val;   /* two ptrs, both are defines */
                PMC* _pmc_val;
            } ptrs;
            INTVAL int_val;
            FLOATVAL num_val;
            struct parrot_string_t * string_val;
        } UnionVal;

So long as the discriminator does not change, the union is type stable. When the discriminator does change, as per here:

void
Parrot_PerlInt_set_string_native(Parrot_Interp interpreter, PMC* pmc, STRING* value)
{
VTABLE_morph(interpreter, pmc, enum_class_PerlString);
VTABLE_set_string_native(interpreter, pmc, value);
}

void
Parrot_perlscalar_morph(Parrot_Interp interpreter, PMC* pmc, INTVAL type)
{
if (pmc->vtable->base_type == enum_class_PerlString) {
if (type == enum_class_PerlString)
return;
PObj_custom_mark_CLEAR(pmc);
pmc->vtable = Parrot_base_vtables[type];
return;
}
if (type == enum_class_PerlString) {
pmc->vtable = Parrot_base_vtables[type];
VTABLE_init(interpreter, pmc);
return;
}
PObj_custom_mark_CLEAR(pmc);
pmc->vtable = Parrot_base_vtables[type];

}


... then these can both run:

        Parrot_scalar_get_string(Parrot_Interp interpreter, PMC* pmc)
        {
            return (STRING*)pmc->cache.string_val;
        }
        
        FLOATVAL
        Parrot_scalar_get_number(Parrot_Interp interpreter, PMC* pmc)
        {
            return pmc->cache.num_val;
        }

That clearly allows a struct parrot_string_t * to freely share the same memory as a double. Were it an int and a double, the "surprising results" from this unprotected access wouldn't violate the no crashes guarantee. But it's a pointer! Dereferencing it could cause a segfault, or a read or write of an arbitrary memory location. Both clearly violate the crucial guarantee.



Gordon Henriksen
[EMAIL PROTECTED]

Reply via email to