|
|
|
|
@ -756,38 +756,51 @@ __objc_compute_ivar_offsets (Class class)
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (class->ivars != 0)
|
|
|
|
|
if (NULL == class->ivars)
|
|
|
|
|
{
|
|
|
|
|
Class super = class_superclass_of_class(class);
|
|
|
|
|
int start = class->ivars->ivar_list[0].ivar_offset;
|
|
|
|
|
/* Quick and dirty test */
|
|
|
|
|
if (Nil != super && start != super->instance_size)
|
|
|
|
|
{
|
|
|
|
|
while (NULL == super->ivars)
|
|
|
|
|
{
|
|
|
|
|
super = class_superclass_of_class(super);
|
|
|
|
|
}
|
|
|
|
|
struct objc_ivar *ivar =
|
|
|
|
|
&super->ivars->ivar_list[super->ivars->ivar_count-1];
|
|
|
|
|
if (start != (ivar->ivar_offset + objc_sizeof_type(ivar->ivar_type)))
|
|
|
|
|
{
|
|
|
|
|
/* Panic if this class has an instance variable that overlaps the
|
|
|
|
|
* superclass. */
|
|
|
|
|
fprintf(stderr,
|
|
|
|
|
"Error: Instance variables in %s overlap superclass %s",
|
|
|
|
|
class->name, super->name);
|
|
|
|
|
fprintf(stderr,
|
|
|
|
|
"Offset of first instance variable, %s, is %d",
|
|
|
|
|
class->ivars->ivar_list[0].ivar_name, start);
|
|
|
|
|
fprintf(stderr,
|
|
|
|
|
"Last instance variable in superclass, %s, ends at offset %d",
|
|
|
|
|
ivar->ivar_name,
|
|
|
|
|
ivar->ivar_offset + objc_sizeof_type(ivar->ivar_type));
|
|
|
|
|
fprintf(stderr, "This probably means that you are subclassing a class from a library, which has changed in a binary-incompatible way.\n");
|
|
|
|
|
abort();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
Class super = class_superclass_of_class(class);
|
|
|
|
|
int start = class->ivars->ivar_list[0].ivar_offset;
|
|
|
|
|
/* Quick and dirty test. If the first ivar comes straight after the last
|
|
|
|
|
* class, then it's fine. */
|
|
|
|
|
if (Nil == super || start == super->instance_size)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
/* Find the last superclass with at least one ivar. */
|
|
|
|
|
while (NULL == super->ivars)
|
|
|
|
|
{
|
|
|
|
|
super = class_superclass_of_class(super);
|
|
|
|
|
}
|
|
|
|
|
struct objc_ivar *ivar =
|
|
|
|
|
&super->ivars->ivar_list[super->ivars->ivar_count-1];
|
|
|
|
|
if (start == (ivar->ivar_offset + objc_sizeof_type(ivar->ivar_type)))
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
/* The classes don't line up, but don't panic; check that the
|
|
|
|
|
* difference is not just padding for alignment */
|
|
|
|
|
int align = objc_alignof_type(class->ivars->ivar_list[0].ivar_type);
|
|
|
|
|
if (start > ivar->ivar_offset &&
|
|
|
|
|
start - ivar->ivar_offset < align)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
/* Panic if this class has an instance variable that overlaps the
|
|
|
|
|
* superclass. */
|
|
|
|
|
fprintf(stderr,
|
|
|
|
|
"Error: Instance variables in %s overlap superclass %s",
|
|
|
|
|
class->name, super->name);
|
|
|
|
|
fprintf(stderr,
|
|
|
|
|
"Offset of first instance variable, %s, is %d",
|
|
|
|
|
class->ivars->ivar_list[0].ivar_name, start);
|
|
|
|
|
fprintf(stderr,
|
|
|
|
|
"Last instance variable in superclass, %s, ends at offset %d",
|
|
|
|
|
ivar->ivar_name,
|
|
|
|
|
ivar->ivar_offset + objc_sizeof_type(ivar->ivar_type));
|
|
|
|
|
fprintf(stderr, "This probably means that you are subclassing a class from a library, which has changed in a binary-incompatible way.\n");
|
|
|
|
|
abort();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|