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]