diff --git a/category.h b/category.h index 2797255..3878ca6 100644 --- a/category.h +++ b/category.h @@ -50,11 +50,11 @@ struct objc_category_legacy /** * The list of instance methods to add to the class. */ - struct objc_method_list *instance_methods; + struct objc_method_list_legacy *instance_methods; /** * The list of class methods to add to the class. */ - struct objc_method_list *class_methods; + struct objc_method_list_legacy *class_methods; /** * The list of protocols adopted by this category. */ diff --git a/class.h b/class.h index dacb3a5..e062d03 100644 --- a/class.h +++ b/class.h @@ -180,7 +180,7 @@ struct legacy_gnustep_objc_class * Metadata for for defining the mappings from selectors to IMPs. Linked * list of method list structures, one per class and one per category. */ - struct objc_method_list *methods; + struct objc_method_list_legacy *methods; /** * The dispatch table for this class. Intialized and maintained by the * runtime. diff --git a/legacy.c b/legacy.c index 90be17a..4ca16b1 100644 --- a/legacy.c +++ b/legacy.c @@ -65,6 +65,23 @@ static struct objc_ivar_list *upgradeIvarList(struct legacy_gnustep_objc_class * return n; } +static struct objc_method_list *upgradeMethodList(struct objc_method_list_legacy *old) +{ + if (old == NULL) + { + return NULL; + } + struct objc_method_list *l = calloc(sizeof(struct objc_method_list) + old->count * sizeof(struct objc_method), 1); + l->count = old->count; + if (old->next) + { + l->next = upgradeMethodList(old->next); + } + l->size = sizeof(struct objc_method); + memcpy(&l->methods, &old->methods, old->count * sizeof(struct objc_method)); + return l; +} + static int legacy_key; PRIVATE struct legacy_gnustep_objc_class* objc_legacy_class_for_class(Class cls) @@ -82,7 +99,7 @@ PRIVATE Class objc_upgrade_class(struct legacy_gnustep_objc_class *oldClass) cls->info = oldClass->info; cls->instance_size = oldClass->instance_size; cls->ivars = upgradeIvarList(oldClass); - cls->methods = oldClass->methods; + cls->methods = upgradeMethodList(oldClass->methods); cls->protocols = oldClass->protocols; cls->abi_version = oldClass->abi_version; cls->properties = oldClass->properties; @@ -99,5 +116,7 @@ PRIVATE struct objc_category *objc_upgrade_category(struct objc_category_legacy { struct objc_category *cat = calloc(1, sizeof(struct objc_category)); memcpy(cat, old, sizeof(struct objc_category_legacy)); + cat->instance_methods = upgradeMethodList(old->instance_methods); + cat->class_methods = upgradeMethodList(old->class_methods); return cat; } diff --git a/method_list.h b/method_list.h index 5a83907..91c3991 100644 --- a/method_list.h +++ b/method_list.h @@ -36,6 +36,30 @@ struct objc_method_list * The number of methods in this list. */ int count; + /** + * Sze of `struct objc_method`. This allows runtimes downgrading newer + * versions of this structure. + */ + size_t size; + /** + * An array of methods. Note that the actual size of this is count. + */ + struct objc_method methods[]; +}; + +/** + * Legacy version of the method list. + */ +struct objc_method_list_legacy +{ + /** + * The next group of methods in the list. + */ + struct objc_method_list_legacy *next; + /** + * The number of methods in this list. + */ + int count; /** * An array of methods. Note that the actual size of this is count. */